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 <akovale...@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 akovale...@apache.org.