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

[ambari] branch trunk updated: AMBARI-23482. NN Federation: service summary widgets should show correct metrics data (akovalenko)

This is an automated email from the ASF dual-hosted git repository.

akovalenko pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 3f6726f  AMBARI-23482. NN Federation: service summary widgets should show correct metrics data (akovalenko)
3f6726f is described below

commit 3f6726f5a44cc5289b141c2cad7c4f35fef6bdc7
Author: Aleksandr Kovalenko <ak...@apache.org>
AuthorDate: Thu Apr 5 21:52:23 2018 +0300

    AMBARI-23482. NN Federation: service summary widgets should show correct metrics data (akovalenko)
---
 .../service/widgets/create/step3_controller.js     |   9 +-
 ambari-web/app/mappers/widget_mapper.js            |   3 +-
 .../app/mixins/common/widgets/widget_mixin.js      |  21 +++--
 ambari-web/app/models/widget.js                    |   1 +
 .../service/widgets/create/step2_add_metric.hbs    |  44 ++++-----
 .../widgets/create/step2_component_dropdown.hbs    |  39 ++++++++
 ambari-web/app/utils/ajax/ajax.js                  |   2 +-
 .../main/service/widgets/create/expression_view.js | 103 +++++++++++++--------
 .../main/service/widgets/create/step2_view.js      |   8 ++
 9 files changed, 158 insertions(+), 72 deletions(-)

diff --git a/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js b/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js
index eebe1f5..10d0b33 100644
--- a/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js
+++ b/ambari-web/app/controllers/main/service/widgets/create/step3_controller.js
@@ -184,7 +184,7 @@ App.WidgetWizardStep3Controller = Em.Controller.extend({
    * @returns {{WidgetInfo: {cluster_name: *, widget_name: *, widget_type: *, description: *, scope: string, metrics: *, values: *, properties: *}}}
    */
   collectWidgetData: function () {
-    return {
+    var widgetData = {
       WidgetInfo: {
         widget_name: this.get('widgetName'),
         widget_type: this.get('content.widgetType'),
@@ -193,6 +193,7 @@ App.WidgetWizardStep3Controller = Em.Controller.extend({
         author: this.get('widgetAuthor'),
         metrics: this.get('widgetMetrics').map(function (metric) {
           delete metric.data;
+          delete metric.tag;
           return metric;
         }),
         values: this.get('widgetValues').map(function (value) {
@@ -202,6 +203,12 @@ App.WidgetWizardStep3Controller = Em.Controller.extend({
         properties: this.get('widgetProperties')
       }
     };
+
+    this.get('widgetMetrics').forEach(function (metric) {
+      if (metric.tag) widgetData.tag = metric.tag;
+    });
+
+    return widgetData;
   },
 
   cancel: function () {
diff --git a/ambari-web/app/mappers/widget_mapper.js b/ambari-web/app/mappers/widget_mapper.js
index 84cb757..c1dac18 100644
--- a/ambari-web/app/mappers/widget_mapper.js
+++ b/ambari-web/app/mappers/widget_mapper.js
@@ -33,7 +33,8 @@ App.widgetMapper = App.QuickDataMapper.create({
     metrics: 'metrics',
     values: 'values',
     description: 'description',
-    scope: 'scope'
+    scope: 'scope',
+    tag: 'tag'
   },
   map: function (json) {
     if (!this.get('model')) return;
diff --git a/ambari-web/app/mixins/common/widgets/widget_mixin.js b/ambari-web/app/mixins/common/widgets/widget_mixin.js
index 3b438f8..0d24f01 100644
--- a/ambari-web/app/mixins/common/widgets/widget_mixin.js
+++ b/ambari-web/app/mixins/common/widgets/widget_mixin.js
@@ -167,7 +167,7 @@ App.WidgetMixin = Ember.Mixin.create({
   getRequestData: function (metrics) {
     var requestsData = {};
     if (metrics) {
-      metrics.forEach(function (metric, index) {
+      metrics.forEach(function (metric) {
         var key;
         if (metric.host_component_criteria) {
           key = metric.service_name + '_' + metric.component_name + '_' + metric.host_component_criteria;
@@ -190,6 +190,7 @@ App.WidgetMixin = Ember.Mixin.create({
             id: requestMetric["metric_path"] + "_" + this.get('metricType'),
             context: this}];
           delete requestMetric["metric_path"];
+          requestMetric.tag = this.get('content.tag');
           requestsData[key] = requestMetric;
         }
       }, this);
@@ -255,16 +256,21 @@ App.WidgetMixin = Ember.Mixin.create({
    */
   getHostComponentMetrics: function (request) {
     var metricPaths = this.prepareMetricPaths(request.metric_paths);
+    var data = {
+      componentName: request.component_name,
+      metricPaths: this.prepareMetricPaths(request.metric_paths),
+      hostComponentCriteria: this.computeHostComponentCriteria(request)
+    };
+
+    if (request.tag) {
+      data.selectedHostsParam = '&HostRoles/host_name.in(' + App.HDFSService.find().objectAt(0).get('masterComponentGroups').findProperty('name', request.tag).hosts.join(',') + ')';
+    }
 
     if (metricPaths.length) {
       var xhr = App.ajax.send({
           name: 'widgets.hostComponent.metrics.get',
           sender: this,
-          data: {
-            componentName: request.component_name,
-            metricPaths: this.prepareMetricPaths(request.metric_paths),
-            hostComponentCriteria: this.computeHostComponentCriteria(request)
-          }
+          data: data
         }),
         graph = this.get('graphView') && this.get('childViews') && this.get('childViews').findProperty('runningRequests');
       if (graph) {
@@ -785,7 +791,8 @@ App.WidgetLoadAggregator = Em.Object.create({
     requests.forEach(function (request) {
       //poll metrics for graph widgets separately
       var graphSuffix = request.context.get('content.widgetType') === "GRAPH" ? "_graph" : '';
-      var id = request.startCallName + "_" + request.data.component_name + graphSuffix;
+      var tagSuffix = request.context.get('content.tag') ? '_' + request.context.get('content.tag') : '';
+      var id = request.startCallName + "_" + request.data.component_name + graphSuffix + tagSuffix;
 
       if (Em.isNone(bulks[id])) {
         bulks[id] = {
diff --git a/ambari-web/app/models/widget.js b/ambari-web/app/models/widget.js
index a618c2e..8c76123 100644
--- a/ambari-web/app/models/widget.js
+++ b/ambari-web/app/models/widget.js
@@ -42,6 +42,7 @@ App.Widget = DS.Model.extend({
   expression: DS.attr('array'),
   metrics: DS.attr('array'),
   values: DS.attr('array'),
+  tag: DS.attr('string'),
   isVisible: DS.attr('boolean', {defaultValue: true}),
   /**
    * @type {number}
diff --git a/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs b/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs
index 31f4e33..2ae091a 100644
--- a/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs
+++ b/ambari-web/app/templates/main/service/widgets/create/step2_add_metric.hbs
@@ -26,30 +26,26 @@
         <li class="dropdown-submenu">
           <a class="" tabindex="-1" href="javascript:void(null);">{{service.displayName}}</a>
           <ul class="dropdown-menu">
-            {{#each component in service.components}}
-              <!--component level-->
-              <li class="dropdown-submenu">
-                <a href="javascript:void(null);">{{component.displayName}}</a>
-                <ul class="dropdown-menu select-options-dropdown">
-                  <!--metrics level-->
-                  <li class="keep-open metric-select" {{action selectComponents component target="view"}}>
-                      {{view App.JqueryChosenView optionsBinding="component.metrics" elementIdBinding="component.id" selectionObjBinding="view.metricsSelectionObj"}}
-                  </li>
-                  <!--select aggregator function -->
-                  <li {{bindAttr class=":keep-open :aggregator-select component.showAggregateSelect::hidden"}}
-                    {{action selectComponents component target="view"}}
-                    {{translateAttr data-original-title="dashboard.widgets.wizard.step2.aggregateTooltip"}}>
-                    {{view App.JqueryChosenView optionsBinding="view.parentView.AGGREGATE_FUNCTIONS" elementIdBinding="component.aggregatorId" selectionObjBinding="view.aggregateFnSelectionObj"}}
-                  </li>
-                  <li class="actions-buttons">
-                    <div>
-                      <button class="btn btn-default" href="#" {{action cancel target="view"}}>{{t common.cancel}}</button>
-                      <button {{bindAttr class=":btn :btn-primary component.isAddEnabled::disabled"}}
-                        {{action addMetric component target="view"}}>{{t common.add}}</button>
-                    </div>
-                  </li>
-                </ul>
-              </li>
+            {{#each comp in service.components}}
+              {{#if comp.isGroup}}
+                <li class="dropdown-submenu">
+                  <a href="javascript:void(null);">{{comp.displayName}}</a>
+                  <ul class="dropdown-menu">
+                    {{#each group in comp.components}}
+                      <li class="dropdown-submenu">
+                        <a href="javascript:void(null);">{{group.displayName}}</a>
+                        <ul class="dropdown-menu">
+                          {{#each groupComponent in group.components}}
+                            {{view App.WidgetWizardComponentDropdownView componentBinding="groupComponent"}}
+                          {{/each}}
+                        </ul>
+                      </li>
+                    {{/each}}
+                  </ul>
+                </li>
+              {{else}}
+                {{view App.WidgetWizardComponentDropdownView componentBinding="comp"}}
+              {{/if}}
             {{/each}}
           </ul>
         </li>
diff --git a/ambari-web/app/templates/main/service/widgets/create/step2_component_dropdown.hbs b/ambari-web/app/templates/main/service/widgets/create/step2_component_dropdown.hbs
new file mode 100644
index 0000000..319aef0
--- /dev/null
+++ b/ambari-web/app/templates/main/service/widgets/create/step2_component_dropdown.hbs
@@ -0,0 +1,39 @@
+{{!
+* 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.
+}}
+<a href="javascript:void(null);">{{view.component.displayName}}</a>
+{{view.component.isGroup}}
+<ul class="dropdown-menu select-options-dropdown">
+  <!--metrics level-->
+  <li class="keep-open metric-select" {{action selectComponents view.component target="view.parentView"}}>
+    {{view App.JqueryChosenView optionsBinding="view.component.metrics" elementIdBinding="view.component.id" selectionObjBinding="view.parentView.metricsSelectionObj"}}
+  </li>
+  <!--select aggregator function -->
+  <li {{bindAttr class=":keep-open :aggregator-select view.component.showAggregateSelect::hidden"}}
+    {{action selectComponents view.component target="view.parentView"}}
+    {{translateAttr data-original-title="dashboard.widgets.wizard.step2.aggregateTooltip"}}>
+    {{view App.JqueryChosenView optionsBinding="view.parentView.parentView.AGGREGATE_FUNCTIONS" elementIdBinding="view.component.aggregatorId" selectionObjBinding="view.parentView.aggregateFnSelectionObj"}}
+  </li>
+  <li class="actions-buttons">
+    <div>
+      <button class="btn btn-default" href="#" {{action cancel target="view.parentView"}}>{{t common.cancel}}</button>
+      <button {{bindAttr class=":btn :btn-primary view.component.isAddEnabled::disabled"}}
+        {{action addMetric view.component target="view.parentView"}}>{{t common.add}}</button>
+    </div>
+  </li>
+</ul>
+
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index af7456b..41c355e 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -3076,7 +3076,7 @@ var urls = {
   },
 
   'widgets.hostComponent.metrics.get': {
-    real: '/clusters/{clusterName}/host_components?HostRoles/component_name={componentName}{hostComponentCriteria}&fields={metricPaths}&format=null_padding',
+    real: '/clusters/{clusterName}/host_components?HostRoles/component_name={componentName}{hostComponentCriteria}&fields={metricPaths}&format=null_padding{selectedHostsParam}',
     mock: '/data/metrics/{serviceName}/Append_num_ops.json'
   },
 
diff --git a/ambari-web/app/views/main/service/widgets/create/expression_view.js b/ambari-web/app/views/main/service/widgets/create/expression_view.js
index 7d4854f..c8f708d 100644
--- a/ambari-web/app/views/main/service/widgets/create/expression_view.js
+++ b/ambari-web/app/views/main/service/widgets/create/expression_view.js
@@ -232,6 +232,9 @@ App.AddMetricExpressionView = Em.View.extend({
         if (self.get('currentSelectedComponent.hostComponentCriteria')) {
           selectedMetric.hostComponentCriteria = self.get('currentSelectedComponent.hostComponentCriteria');
         }
+        if (self.get('currentSelectedComponent.tag')) {
+          selectedMetric.tag = self.get('currentSelectedComponent.tag');
+        }
         self.set('currentSelectedComponent.selectedMetric', selectedMetric);
         if (self.get('currentSelectedComponent.selectedAggregation') == Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps')) {
           var defaultAggregator = self.get('parentView.AGGREGATE_FUNCTIONS')[0];
@@ -263,9 +266,7 @@ App.AddMetricExpressionView = Em.View.extend({
    * @param {object} event
    */
   selectComponents: function (event) {
-    var component = this.get('componentMap').findProperty('serviceName', event.context.get('serviceName'))
-      .get('components').findProperty('id', event.context.get('id'));
-    this.set('currentSelectedComponent', component);
+    this.set('currentSelectedComponent', event.context);
     event.stopPropagation();
   },
 
@@ -310,13 +311,18 @@ App.AddMetricExpressionView = Em.View.extend({
    * has following hierarchy: service -> component -> metrics
    */
   componentMap: function () {
+    var hasNameNodeFederation = App.get('hasNameNodeFederation');
     var servicesMap = {};
     var result = [];
+    var nameServiceGroups = [];
     var masterNames = App.StackServiceComponent.find().filterProperty('isMaster').mapProperty('componentName');
     var parentView = this.get('parentView');
     var expressionId = "_" + parentView.get('expression.id');
     if (this.get('controller.filteredMetrics')) {
       this.get('controller.filteredMetrics').forEach(function (metric) {
+        // ignore NameNode component level metrics on federated cluster
+        if (hasNameNodeFederation && metric.component_name === 'NAMENODE' && metric.level === 'COMPONENT') return false;
+
         var service = servicesMap[metric.service_name];
         if (!service) {
           service = {
@@ -343,48 +349,35 @@ App.AddMetricExpressionView = Em.View.extend({
       }, this);
     }
 
+    if (hasNameNodeFederation) {
+      App.HDFSService.find().objectAt(0).get('masterComponentGroups').forEach(function(group) {
+        nameServiceGroups.push({
+          displayName: group.name,
+          components: []
+        });
+      });
+    }
+
     for (var serviceName in servicesMap) {
       var components = [];
       for (var componentId in servicesMap[serviceName].components) {
         // Hide the option if none of the hostComponent is created in the cluster yet
         var componentName = servicesMap[serviceName].components[componentId].component_name;
         if (App.HostComponent.getCount(componentName, 'totalCount') === 0) continue;
-        var component = Em.Object.create({
-          componentName: servicesMap[serviceName].components[componentId].component_name,
-          level: servicesMap[serviceName].components[componentId].level,
-          displayName: function() {
-            var stackComponent = App.StackServiceComponent.find(this.get('componentName'));
-            if (stackComponent.get('isMaster')) {
-              if (this.get('level') === 'HOSTCOMPONENT') {
-                return Em.I18n.t('widget.create.wizard.step2.activeComponents').format(stackComponent.get('displayName'));
-              }
-            }
-            return Em.I18n.t('widget.create.wizard.step2.allComponents').format(pluralize(stackComponent.get('displayName')));
-          }.property('componentName', 'level'),
-          count: servicesMap[serviceName].components[componentId].count,
-          metrics: servicesMap[serviceName].components[componentId].metrics.uniq().sort(),
-          selected: false,
-          id: componentId + expressionId,
-          aggregatorId: componentId + expressionId + '_aggregator',
-          serviceName: serviceName,
-          showAggregateSelect: Em.computed.equal('level', 'COMPONENT'),
-          selectedMetric: null,
-          selectedAggregation: Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps'),
-          isAddEnabled: function () {
-            var selectedMetric = this.get('selectedMetric'),
-              aggregateFunction = this.get('selectedAggregation');
-            if (this.get('showAggregateSelect')) {
-              return (!!selectedMetric && !!aggregateFunction &&
-                aggregateFunction != Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps'));
-            } else {
-              return (!!selectedMetric);
-            }
-          }.property('selectedMetric', 'selectedAggregation')
-        });
-        if (component.get('level') === 'HOSTCOMPONENT') {
-          component.set('hostComponentCriteria', servicesMap[serviceName].components[componentId].hostComponentCriteria);
+        if (hasNameNodeFederation && componentName === 'NAMENODE') {
+          nameServiceGroups.forEach(function(group) {
+            group.components.push(this.createComponentItem(servicesMap[serviceName], serviceName, componentId, expressionId, group.displayName));
+          }, this);
+        } else {
+          components.push(this.createComponentItem(servicesMap[serviceName], serviceName, componentId, expressionId));
         }
-        components.push(component);
+      }
+      if (hasNameNodeFederation && serviceName === 'HDFS') {
+        components.push(Em.Object.create({
+          displayName: 'NameNodes',
+          isGroup: true,
+          components: nameServiceGroups
+        }));
       }
       result.push(Em.Object.create({
         serviceName: serviceName,
@@ -399,6 +392,40 @@ App.AddMetricExpressionView = Em.View.extend({
     return this.putContextServiceOnTop(result);
   }.property('controller.filteredMetrics', 'App.router.clusterController.isComponentsStateLoaded'),
 
+  createComponentItem: function (service, serviceName, componentId, expressionId, tag) {
+    var stackComponent = App.StackServiceComponent.find(service.components[componentId].component_name);
+    var component = service.components[componentId];
+    tag = tag || '';
+    return Em.Object.create({
+      componentName: component.component_name,
+      level: component.level,
+      displayName: stackComponent.get('isMaster') && component.level  === 'HOSTCOMPONENT' ?
+        Em.I18n.t('widget.create.wizard.step2.activeComponents').format(stackComponent.get('displayName')) :
+        Em.I18n.t('widget.create.wizard.step2.allComponents').format(pluralize(stackComponent.get('displayName'))),
+      tag: tag,
+      count: component.count,
+      metrics: component.metrics.uniq().sort(),
+      selected: false,
+      id: componentId + expressionId + tag,
+      aggregatorId: componentId + expressionId + '_aggregator',
+      serviceName: serviceName,
+      showAggregateSelect: Em.computed.equal('level', 'COMPONENT'),
+      selectedMetric: null,
+      selectedAggregation: Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps'),
+      hostComponentCriteria: component.level === 'HOSTCOMPONENT' ? component.hostComponentCriteria : null,
+      isAddEnabled: function () {
+        var selectedMetric = this.get('selectedMetric'),
+          aggregateFunction = this.get('selectedAggregation');
+        if (this.get('showAggregateSelect')) {
+          return (!!selectedMetric && !!aggregateFunction &&
+          aggregateFunction != Em.I18n.t('dashboard.widgets.wizard.step2.aggregateFunction.scanOps'));
+        } else {
+          return (!!selectedMetric);
+        }
+      }.property('selectedMetric', 'selectedAggregation')
+    });
+  },
+
   /**
    * returns the input array with the context service (service from which widget browser is launched) as the first element of the array
    * @param serviceComponentMap {Array}
diff --git a/ambari-web/app/views/main/service/widgets/create/step2_view.js b/ambari-web/app/views/main/service/widgets/create/step2_view.js
index 24a43da..d43130f 100644
--- a/ambari-web/app/views/main/service/widgets/create/step2_view.js
+++ b/ambari-web/app/views/main/service/widgets/create/step2_view.js
@@ -93,5 +93,13 @@ App.WidgetPropertySelectView = Em.Select.extend({
   }
 });
 
+App.WidgetWizardComponentDropdownView = Em.View.extend({
 
+  templateName: require('templates/main/service/widgets/create/step2_component_dropdown'),
+
+  tagName: 'li',
+
+  classNames: ['dropdown-submenu']
+
+});
 

-- 
To stop receiving notification emails like this one, please contact
akovalenko@apache.org.