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.