AMBARI-19678 Confirmation for adding host component from service summary page should be displayed once. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3871f4a8 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3871f4a8 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3871f4a8 Branch: refs/heads/branch-dev-patch-upgrade Commit: 3871f4a8d31aff1f61bad695ec5eb884820638c0 Parents: 796658f Author: ababiichuk <[email protected]> Authored: Mon Jan 23 19:47:11 2017 +0200 Committer: ababiichuk <[email protected]> Committed: Mon Jan 23 20:36:07 2017 +0200 ---------------------------------------------------------------------- ambari-web/app/controllers/main/host/details.js | 202 +++++++++++++++---- ambari-web/app/controllers/main/service/item.js | 58 +----- .../host/details/addDeleteComponentPopup.hbs | 34 +++- .../templates/main/service/add_host_popup.hbs | 33 --- .../test/controllers/main/host/details_test.js | 144 +++++++++++-- 5 files changed, 317 insertions(+), 154 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/3871f4a8/ambari-web/app/controllers/main/host/details.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js index 1fcc14d..093603e 100644 --- a/ambari-web/app/controllers/main/host/details.js +++ b/ambari-web/app/controllers/main/host/details.js @@ -89,27 +89,32 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow 'HIVE_METASTORE': { deletePropertyName: 'deleteHiveMetaStore', hostPropertyName: 'hiveMetastoreHost', - configsCallbackName: 'loadHiveConfigs' + configTagsCallbackName: 'loadHiveConfigs', + configsCallbackName: 'onLoadHiveConfigs' }, 'WEBHCAT_SERVER': { deletePropertyName: 'deleteWebHCatServer', hostPropertyName: 'webhcatServerHost', - configsCallbackName: 'loadWebHCatConfigs' + configTagsCallbackName: 'loadWebHCatConfigs', + configsCallbackName: 'onLoadHiveConfigs' }, 'HIVE_SERVER': { addPropertyName: 'addHiveServer', deletePropertyName: 'deleteHiveServer', - configsCallbackName: 'loadHiveConfigs' + configTagsCallbackName: 'loadHiveConfigs', + configsCallbackName: 'onLoadHiveConfigs' }, 'NIMBUS': { deletePropertyName: 'deleteNimbusHost', hostPropertyName: 'nimbusHost', - configsCallbackName: 'loadStormConfigs' + configTagsCallbackName: 'loadStormConfigs', + configsCallbackName: 'onLoadStormConfigs' }, 'RANGER_KMS_SERVER': { deletePropertyName: 'deleteRangerKMSServer', hostPropertyName: 'rangerKMSServerHost', - configsCallbackName: 'loadRangerConfigs' + configTagsCallbackName: 'loadRangerConfigs', + configsCallbackName: 'onLoadRangerConfigs' } }, @@ -158,6 +163,12 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow isReconfigureRequired: false, /** + * Contains component-related config properties loaded from server + * @type {Object|null} + */ + configs: null, + + /** * Array of all properties affected by adding/deleting host component * @type {Array} */ @@ -189,16 +200,38 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow manualKerberosWarning: App.get('router.mainAdminKerberosController.isManualKerberos') ? Em.I18n.t('hosts.host.manualKerberosWarning') : '', lastComponent: false, - lastComponentError: '' + lastComponentError: '', + hasHostsSelect: false, + selectedHost: null, + anyHostsWithoutComponent: true }), - clearConfigsChanges: function () { + saveLoadedConfigs: function (data) { + var configs = { + items: [] + }; + data.items.forEach(function (item) { + var configTypeObject = Em.getProperties(item, ['type', 'properties_attributes']), + properties = {}; + Em.keys(item.properties).forEach(function (propertyName) { + properties[propertyName] = item.properties[propertyName]; + }); + configTypeObject.properties = properties; + configs.items.push(configTypeObject); + }); + this.set('configs', configs); + }, + + clearConfigsChanges: function (shouldKeepLoadedConfigs) { var arrayNames = ['allPropertiesToChange', 'recommendedPropertiesToChange', 'requiredPropertiesToChange', 'groupedPropertiesToChange']; this.abortRequests(); arrayNames.forEach(function (arrayName) { this.get(arrayName).clear(); }, this); this.set('isReconfigureRequired', false); + if (!shouldKeepLoadedConfigs) { + this.set('configs', null); + } }, applyConfigsCustomization: function () { @@ -456,7 +489,6 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow var component = event.context; var componentName = component.get('componentName'); var displayName = component.get('displayName'); - var hostName = event.selectedHost || this.get('content.hostName'); var returnFunc; var componentsMapItem = this.get('addDeleteComponentsMap')[componentName]; if (componentsMapItem) { @@ -465,7 +497,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow } this.clearConfigsChanges(); this.set('isReconfigureRequired', true); - returnFunc = this.showDeleteComponentPopup(component, componentsMapItem.configsCallbackName); + returnFunc = this.showDeleteComponentPopup(component); } else if (componentName === 'JOURNALNODE') { returnFunc = App.showConfirmationPopup(function () { App.router.transitionTo('main.services.manageJournalNode'); @@ -476,18 +508,20 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow return returnFunc; }, - showDeleteComponentPopup: function (component, callbackName) { + showDeleteComponentPopup: function (component) { var self = this, isLastComponent = (this.getTotalComponent(component) === 1), componentName = component.get('componentName'), componentDisplayName = component.get('displayName'), - commonMessage = Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(componentDisplayName); - if (this.get('isReconfigureRequired')) { - this.set('isConfigsLoadingInProgress', true); - this.isServiceMetricsLoaded(function () { - self.loadConfigs(callbackName); - }); + componentsMapItem = this.get('addDeleteComponentsMap')[componentName], + commonMessage = Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(componentDisplayName), + configTagsCallbackName, + configsCallbackName; + if (componentsMapItem) { + configTagsCallbackName = componentsMapItem.configTagsCallbackName; + configsCallbackName = componentsMapItem.configsCallbackName; } + this.loadComponentRelatedConfigs(configTagsCallbackName, configsCallbackName); return App.ModalPopup.show({ header: Em.I18n.t('popup.confirmation.commonHeader'), controller: self, @@ -711,9 +745,10 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow returnFunc, self = this, component = event.context, - hostName = event.selectedHost || this.get('content.hostName'), + hostName = this.get('content.hostName'), componentName = component.get('componentName'), - missedComponents = event.selectedHost ? [] : this.checkComponentDependencies(componentName, { + hasHostsSelect = event.hasOwnProperty('selectedHost'), + missedComponents = hasHostsSelect ? [] : this.checkComponentDependencies(componentName, { scope: 'host', installedComponents: this.get('content.hostComponents').mapProperty('componentName') }), @@ -742,29 +777,40 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow } this.clearConfigsChanges(); this.set('isReconfigureRequired', true); - returnFunc = self.showAddComponentPopup(component, hostName, null, componentsMapItem.configsCallbackName, primary); + returnFunc = self.showAddComponentPopup(component, hostName, null, primary, hasHostsSelect); } else if (componentName === 'JOURNALNODE') { returnFunc = App.showConfirmationPopup(function () { App.router.transitionTo('main.services.manageJournalNode'); }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); } else { returnFunc = this.showAddComponentPopup(component, hostName, function () { + if (hasHostsSelect) { + hostName = self.get('content.hostName'); + } self.installHostComponentCall(hostName, component); - }); + }, null, hasHostsSelect); } return returnFunc; }, - showAddComponentPopup: function (component, hostName, primary, callbackName, primaryOnReconfigure) { + showAddComponentPopup: function (component, hostName, primary, primaryOnReconfigure, hasHostsSelect) { var self = this, componentName = component.get('componentName'), componentDisplayName = component.get('displayName'), - commonMessage = Em.I18n.t('hosts.host.addComponent.msg').format(componentDisplayName); - if (this.get('isReconfigureRequired')) { - this.set('isConfigsLoadingInProgress', true); - this.isServiceMetricsLoaded(function () { - self.loadConfigs(callbackName); - }); + componentsMapItem = this.get('addDeleteComponentsMap')[componentName], + commonMessage = Em.I18n.t('hosts.host.addComponent.msg').format(componentDisplayName), + configTagsCallbackName, + configsCallbackName; + if (componentsMapItem) { + configTagsCallbackName = componentsMapItem.configTagsCallbackName || 'loadConfigsSuccessCallback'; + configsCallbackName = componentsMapItem.configsCallbackName || 'saveZkConfigs'; + } + if (hasHostsSelect) { + if (this.get('isReconfigureRequired')) { + this.set('isConfigsLoadingInProgress', true); + } + } else { + this.loadComponentRelatedConfigs(configTagsCallbackName, configsCallbackName); } return App.ModalPopup.show({ header: Em.I18n.t('popup.confirmation.commonHeader'), @@ -776,7 +822,51 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow }.property('controller.hasPropertiesToChange'), primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'), bodyClass: self.get('addDeleteComponentPopupBody').extend({ - commonMessage: commonMessage + commonMessage: commonMessage, + hasHostsSelect: hasHostsSelect, + addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(componentDisplayName), + selectHostMsg: Em.I18n.t('services.summary.selectHostForComponent').format(componentDisplayName), + thereIsNoHostsMsg: Em.I18n.t('services.summary.allHostsAlreadyRunComponent').format(componentDisplayName), + hostsWithoutComponent: function () { + if (this.get('hasHostsSelect')) { + var hostsWithComponent = App.HostComponent.find().filterProperty('componentName', componentName).mapProperty('hostName'), + result = App.get('allHostNames'); + hostsWithComponent.forEach(function (host) { + result = result.without(host); + }); + return result; + } else { + return []; + } + }.property('hasHostsSelect'), + anyHostsWithoutComponent: Em.computed.or('!hasHostsSelect', 'hostsWithoutComponent.length'), + selectedHostObserver: function () { + hostName = this.get('selectedHost'); + self.clearConfigsChanges(true); + if (!self.get('content')) { + self.set('content', {}); + } + self.setProperties({ + 'isReconfigureRequired': !!componentsMapItem, + 'content.hostName': hostName + }); + if (componentsMapItem) { + var configs = self.get('configs'), + params = configs && configs.params || {}; + if (componentsMapItem.hostPropertyName) { + self.set(componentsMapItem.hostPropertyName, hostName); + } + if (componentsMapItem.addPropertyName) { + self.set(componentsMapItem.addPropertyName, true); + } + if (configs) { + this.set('isConfigsLoadingInProgress', true); + self[configsCallbackName](configs, null, params); + } else { + self.loadComponentRelatedConfigs(configTagsCallbackName, configsCallbackName); + } + } + }.observes('selectedHost') }), disablePrimary: Em.computed.and('controller.isReconfigureRequired', 'controller.isConfigsLoadingInProgress'), onPrimary: function () { @@ -803,6 +893,16 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow }); }, + loadComponentRelatedConfigs: function (configTagsCallbackName, configsCallbackName) { + var self = this; + if (this.get('isReconfigureRequired')) { + this.set('isConfigsLoadingInProgress', true); + this.isServiceMetricsLoaded(function () { + self.loadConfigs(configTagsCallbackName, configsCallbackName); + }); + } + }, + /** * Success callback for install host component request (sent in <code>addNewComponentSuccessCallback</code>) * @param {object} data @@ -870,16 +970,18 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * Success callback for Storm load configs request * @param {object} data + * @param {object} opt + * @param {object} params * @method loadStormConfigs */ - loadStormConfigs: function (data) { + loadStormConfigs: function (data, opt, params) { var request = App.ajax.send({ name: 'admin.get.all_configurations', sender: this, data: { urlParams: '(type=storm-site&tag=' + data.Clusters.desired_configs['storm-site'].tag + ')' }, - success: 'onLoadStormConfigs' + success: params.callback }); this.trackRequest(request); }, @@ -975,6 +1077,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow attributes = {}, propertiesToChange = this.get('allPropertiesToChange'); + this.saveLoadedConfigs(data); data.items.forEach(function (item) { configs[item.type] = item.properties; attributes[item.type] = item.properties_attributes || {}; @@ -1015,9 +1118,11 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * Success callback for load configs request * @param {object} data + * @param {object} opt + * @param {object} params * @method loadWebHCatConfigs */ - loadWebHCatConfigs: function (data) { + loadWebHCatConfigs: function (data, opt, params) { var request = App.ajax.send({ name: 'admin.get.all_configurations', sender: this, @@ -1030,7 +1135,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow '(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')' ].join('|') }, - success: 'onLoadHiveConfigs' + success: params.callback }); this.trackRequest(request); return request; @@ -1043,7 +1148,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow * @param {object} params * @method loadHiveConfigs */ - loadHiveConfigs: function (data) { + loadHiveConfigs: function (data, opt, params) { var request = App.ajax.send({ name: 'admin.get.all_configurations', sender: this, @@ -1055,7 +1160,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow '(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')' ].join('|') }, - success: 'onLoadHiveConfigs' + success: params.callback }); this.trackRequest(request); return request; @@ -1082,6 +1187,10 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow hiveMetastorePort: "" }; var initializer = params.webHCat ? App.AddWebHCatComponentsInitializer : App.AddHiveComponentsInitializer; + this.saveLoadedConfigs(data); + this.set('configs.params', { + webHCat: params.webHCat + }); data.items.forEach(function (item) { configs[item.type] = item.properties; attributes[item.type] = item.properties_attributes || {}; @@ -1275,16 +1384,18 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * Success callback for load configs request * @param {object} data + * @param {object} opt + * @param {object} params * @method loadRangerConfigs */ - loadRangerConfigs: function (data) { + loadRangerConfigs: function (data, opt, params) { var request = App.ajax.send({ name: 'admin.get.all_configurations', sender: this, data: { urlParams: '(type=core-site&tag=' + data.Clusters.desired_configs['core-site'].tag + ')|(type=hdfs-site&tag=' + data.Clusters.desired_configs['hdfs-site'].tag + ')|(type=kms-env&tag=' + data.Clusters.desired_configs['kms-env'].tag + ')' }, - success: 'onLoadRangerConfigs' + success: params.callback }); this.trackRequest(request); }, @@ -1325,6 +1436,8 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow ], propertiesToChange = this.get('allPropertiesToChange'); + this.saveLoadedConfigs(data); + properties.forEach(function (property) { var typeConfigs = data.items.findProperty('type', property.type).properties, currentValue = typeConfigs[property.name], @@ -1453,11 +1566,14 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow * This is required to make sure that service metrics API determining the HA state of components is loaded * @method loadConfigs */ - loadConfigs: function (callback) { + loadConfigs: function (configTagsCallback, configsCallback) { var request = App.ajax.send({ name: 'config.tags', sender: this, - success: callback ? callback : 'loadConfigsSuccessCallback', + data: { + callback: configsCallback || 'saveZkConfigs' + }, + success: configTagsCallback || 'loadConfigsSuccessCallback', error: 'onLoadConfigsErrorCallback' }); this.trackRequest(request); @@ -1474,9 +1590,11 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * Success callback for load configs request * @param {object} data + * @param {object} opt + * @param {object} params * @method loadConfigsSuccessCallback */ - loadConfigsSuccessCallback: function (data) { + loadConfigsSuccessCallback: function (data, opt, params) { var urlParams = this.constructConfigUrlParams(data); if (urlParams.length > 0) { var request = App.ajax.send({ @@ -1485,7 +1603,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow data: { urlParams: urlParams.join('|') }, - success: 'saveZkConfigs' + success: params.callback || 'saveZkConfigs' }); this.trackRequest(request); return true; @@ -1524,6 +1642,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow saveZkConfigs: function (data) { var configs = {}; var attributes = {}; + this.saveLoadedConfigs(data); data.items.forEach(function (item) { configs[item.type] = item.properties; attributes[item.type] = item.properties_attributes || {}; @@ -2524,7 +2643,6 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow }); }, deleteHostSuccessCallback: function (data, rq, requestBody) { - var self = this; App.router.get('updateController').updateHost(function () { App.router.transitionTo('hosts.index'); }); @@ -2535,7 +2653,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow deleteHostErrorCallback: function (xhr, textStatus, errorThrown, opt) { xhr.responseText = "{\"message\": \"" + xhr.statusText + "\"}"; var self = this; - var callback = function () { + var callback = function () { self.loadConfigs(); }; self.isServiceMetricsLoaded(callback); http://git-wip-us.apache.org/repos/asf/ambari/blob/3871f4a8/ambari-web/app/controllers/main/service/item.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/item.js b/ambari-web/app/controllers/main/service/item.js index 3a60137..9758ac3 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/ambari-web/app/controllers/main/service/item.js @@ -937,63 +937,15 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow * @param componentName */ addComponent: function (componentName) { - var self = this; var component = App.StackServiceComponent.find().findProperty('componentName', componentName); - var componentDisplayName = component.get('displayName'); App.get('router.mainAdminKerberosController').getKDCSessionState(function () { - return App.ModalPopup.show({ - primary: Em.computed.ifThenElse('anyHostsWithoutComponent', Em.I18n.t('hosts.host.addComponent.popup.confirm'), undefined), - - header: Em.I18n.t('popup.confirmation.commonHeader'), - - addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(componentDisplayName), - - selectHostMsg: Em.computed.i18nFormat('services.summary.selectHostForComponent', 'componentDisplayName'), - - thereIsNoHostsMsg: Em.computed.i18nFormat('services.summary.allHostsAlreadyRunComponent', 'componentDisplayName'), - - hostsWithoutComponent: function () { - var hostsWithComponent = App.HostComponent.find().filterProperty('componentName', componentName).mapProperty('hostName'); - var result = App.get('allHostNames'); - - hostsWithComponent.forEach(function (host) { - result = result.without(host); - }); - - return result; - }.property(), - - anyHostsWithoutComponent: Em.computed.gt('hostsWithoutComponent.length', 0), - - selectedHost: null, - - componentName: componentName, - - componentDisplayName: componentDisplayName, - - bodyClass: Em.View.extend({ - templateName: require('templates/main/service/add_host_popup') - }), - - onPrimary: function () { - var selectedHost = this.get('selectedHost'); - - // Install - if (['HIVE_METASTORE', 'RANGER_KMS_SERVER', 'NIMBUS'].contains(component.get('componentName')) && !!selectedHost) { - App.router.get('mainHostDetailsController').addComponentWithCheck( - { - context: component, - selectedHost: selectedHost - } - ); - } else { - self.installHostComponentCall(selectedHost, component); - } - - this.hide(); + App.router.get('mainHostDetailsController').addComponentWithCheck( + { + context: component, + selectedHost: null } - }); + ); }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/3871f4a8/ambari-web/app/templates/main/host/details/addDeleteComponentPopup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/host/details/addDeleteComponentPopup.hbs b/ambari-web/app/templates/main/host/details/addDeleteComponentPopup.hbs index ed8445e..2aa5e71 100644 --- a/ambari-web/app/templates/main/host/details/addDeleteComponentPopup.hbs +++ b/ambari-web/app/templates/main/host/details/addDeleteComponentPopup.hbs @@ -24,17 +24,29 @@ </div> </div> {{/if}} -{{#if controller.isReconfigureRequired}} - {{#if controller.isConfigsLoadingInProgress}} - {{view App.SpinnerView}} - {{else}} - {{view.commonMessage}} - {{#if controller.hasPropertiesToChange}} - {{view App.DependentConfigsListView isAfterRecommendation=false recommendationsBinding="controller.recommendedPropertiesToChange" requiredChangesBinding="controller.requiredPropertiesToChange"}} +{{#if view.anyHostsWithoutComponent}} + {{#if view.hasHostsSelect}} + <div>{{view.selectHostMsg}}</div> + <div class="row"> + <div class="col-md-12"> + {{view Ember.Select contentBinding="view.hostsWithoutComponent" selectionBinding="view.selectedHost" classNames="form-control"}} + </div> + </div> + {{/if}} + {{#if controller.isReconfigureRequired}} + {{#if controller.isConfigsLoadingInProgress}} + {{view App.SpinnerView}} + {{else}} + {{view.commonMessage}} + {{#if controller.hasPropertiesToChange}} + {{view App.DependentConfigsListView isAfterRecommendation=false recommendationsBinding="controller.recommendedPropertiesToChange" requiredChangesBinding="controller.requiredPropertiesToChange"}} + {{/if}} + {{{view.manualKerberosWarning}}} {{/if}} - {{{view.manualKerberosWarning}}} + {{else}} + <div>{{view.commonMessage}}</div> + <div>{{{view.manualKerberosWarning}}}</div> {{/if}} {{else}} - <div>{{view.commonMessage}}</div> - <div>{{{view.manualKerberosWarning}}}</div> -{{/if}} + {{view.thereIsNoHostsMsg}} +{{/if}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/3871f4a8/ambari-web/app/templates/main/service/add_host_popup.hbs ---------------------------------------------------------------------- diff --git a/ambari-web/app/templates/main/service/add_host_popup.hbs b/ambari-web/app/templates/main/service/add_host_popup.hbs deleted file mode 100644 index e5f2c99..0000000 --- a/ambari-web/app/templates/main/service/add_host_popup.hbs +++ /dev/null @@ -1,33 +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. -}} - -{{#if anyHostsWithoutComponent}} - <p>{{selectHostMsg}}</p> - <div class="row"> - <div class="col-md-12"> - {{view Ember.Select contentBinding="hostsWithoutComponent" selectionBinding="selectedHost" classNames="form-control"}} - </div> - </div> - <div class="row"> - <div class="col-md-12"> - <p>{{addComponentMsg}}</p> - </div> - </div> -{{else}} - <p>{{thereIsNoHostsMsg}}</p> -{{/if}} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/3871f4a8/ambari-web/test/controllers/main/host/details_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/host/details_test.js b/ambari-web/test/controllers/main/host/details_test.js index ff5887c..4eccf95 100644 --- a/ambari-web/test/controllers/main/host/details_test.js +++ b/ambari-web/test/controllers/main/host/details_test.js @@ -594,7 +594,7 @@ describe('App.MainHostDetailsController', function () { tag: 'tag' } } - }}); + }}, null, {}); var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(controller); @@ -619,6 +619,7 @@ describe('App.MainHostDetailsController', function () { sinon.stub(controller, 'getStormNimbusHosts').returns("host1"); sinon.stub(controller, 'updateZkConfigs', Em.K); sinon.stub(controller, 'saveConfigsBatch', Em.K); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); controller.set('nimbusHost', 'host2'); controller.onLoadStormConfigs(data); }); @@ -626,6 +627,7 @@ describe('App.MainHostDetailsController', function () { controller.getStormNimbusHosts.restore(); controller.updateZkConfigs.restore(); controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); it("updateZkConfigs called with valid arguments", function() { expect(controller.updateZkConfigs.calledWith({'storm-site': { @@ -665,7 +667,7 @@ describe('App.MainHostDetailsController', function () { tag: 'tag' } } - }}); + }}, null, {}); var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(controller); @@ -689,7 +691,7 @@ describe('App.MainHostDetailsController', function () { tag: 'tag' } } - }}); + }}, null, {}); var args = testHelpers.findAjaxRequest('name', 'admin.get.all_configurations'); expect(args[0]).exists; expect(args[0].sender).to.be.eql(controller); @@ -952,7 +954,7 @@ describe('App.MainHostDetailsController', function () { }); it('url params is empty', function () { - expect(controller.loadConfigsSuccessCallback()).to.be.false; + expect(controller.loadConfigsSuccessCallback(null, null, {})).to.be.false; var args = testHelpers.findAjaxRequest('name', 'reassign.load_configs'); expect(args).not.exists; }); @@ -1018,6 +1020,7 @@ describe('App.MainHostDetailsController', function () { beforeEach(function () { sinon.stub(controller, 'saveConfigsBatch', Em.K); sinon.stub(controller, 'updateZkConfigs', Em.K); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); sinon.stub(App.Service, 'find', function() { return [ Em.Object.create({ serviceName: 'HIVE' }), @@ -1034,6 +1037,7 @@ describe('App.MainHostDetailsController', function () { App.Service.find.restore(); controller.updateZkConfigs.restore(); controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); it('configs for YARN', function () { @@ -3270,11 +3274,13 @@ describe('App.MainHostDetailsController', function () { ]; beforeEach(function () { - sinon.spy(controller, 'saveConfigsBatch') + sinon.spy(controller, 'saveConfigsBatch'); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); }); afterEach(function () { controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); cases.forEach(function (item) { @@ -3518,10 +3524,13 @@ describe('App.MainHostDetailsController', function () { beforeEach(function() { sinon.stub(controller, 'saveConfigsBatch', Em.K); + sinon.stub(controller, 'saveLoadedConfigs', Em.K); + controller.set('configs', {}); }); afterEach(function() { controller.saveConfigsBatch.restore(); + controller.saveLoadedConfigs.restore(); }); var makeHostComponentModel = function(componentName, hostNames) { @@ -3960,29 +3969,134 @@ describe('App.MainHostDetailsController', function () { recommendedPropertiesToChange: [{}], requiredPropertiesToChange: [{}], groupedPropertiesToChange: [{}], - isReconfigureRequired: true + isReconfigureRequired: true, + configs: {} }); - controller.clearConfigsChanges(); }); afterEach(function () { controller.abortRequests.restore(); }); - it('allPropertiesToChange', function () { - expect(controller.get('allPropertiesToChange')).to.have.length(0); + describe('default case', function () { + + beforeEach(function () { + controller.clearConfigsChanges(); + }); + + it('allPropertiesToChange', function () { + expect(controller.get('allPropertiesToChange')).to.have.length(0); + }); + + it('recommendedPropertiesToChange', function () { + expect(controller.get('recommendedPropertiesToChange')).to.have.length(0); + }); + + it('groupedPropertiesToChange', function () { + expect(controller.get('groupedPropertiesToChange')).to.have.length(0); + }); + + it('isReconfigureRequired', function () { + expect(controller.get('isReconfigureRequired')).to.be.false; + }); + + it('configs', function () { + expect(controller.get('configs')).to.be.null; + }); + }); - it('recommendedPropertiesToChange', function () { - expect(controller.get('recommendedPropertiesToChange')).to.have.length(0); + describe('no loaded configs cleanup', function () { + + beforeEach(function () { + controller.clearConfigsChanges(true); + }); + + it('configs shouldn\'t be cleared', function () { + expect(controller.get('configs')).to.not.be.null; + }); + }); - it('groupedPropertiesToChange', function () { - expect(controller.get('groupedPropertiesToChange')).to.have.length(0); + }); + + describe('#saveLoadedConfigs', function () { + + var data = { + items: [ + { + type: 't0', + properties: { + p0: 'v0', + p1: 'v1' + }, + properties_attributes: {} + }, + { + type: 't1', + properties: { + p2: 'v2', + p3: 'v3' + }, + properties_attributes: {} + } + ] + }; + + it('should store data in configs object', function () { + controller.set('configs', null); + controller.saveLoadedConfigs(data); + expect(controller.get('configs')).to.eql(data); }); - it('isReconfigureRequired', function () { - expect(controller.get('isReconfigureRequired')).to.be.false; + }); + + describe('#loadComponentRelatedConfigs', function () { + + var testCases = [ + { + isReconfigureRequired: true, + loadConfigsCallCount: 1, + isConfigsLoadingInProgress: true, + message: 'reconfigure required' + }, + { + isReconfigureRequired: false, + loadConfigsCallCount: 0, + isConfigsLoadingInProgress: false, + message: 'no reconfigure required' + } + ]; + + testCases.forEach(function (test) { + + describe(test.message, function () { + + beforeEach(function () { + sinon.stub(controller, 'isServiceMetricsLoaded', Em.clb); + sinon.stub(controller, 'loadConfigs', Em.K); + controller.setProperties({ + isReconfigureRequired: test.isReconfigureRequired, + isConfigsLoadingInProgress: false + }); + controller.loadComponentRelatedConfigs(); + }); + + afterEach(function () { + controller.isServiceMetricsLoaded.restore(); + controller.loadConfigs.restore(); + }); + + it('loadConfigs', function () { + expect(controller.loadConfigs.callCount).to.equal(test.loadConfigsCallCount); + }); + + it('isConfigsLoadingInProgress', function () { + expect(controller.get('isConfigsLoadingInProgress')).to.equal(test.isConfigsLoadingInProgress); + }); + + }); + }); });
