AMBARI-20143 Merge changes in branch-feature-preview-configs to branch-2.5. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/304bd060 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/304bd060 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/304bd060 Branch: refs/heads/branch-2.5 Commit: 304bd060536ad1f5b153657862e91a8b96411167 Parents: ac19fd1 Author: ababiichuk <[email protected]> Authored: Thu Feb 23 15:15:20 2017 +0200 Committer: ababiichuk <[email protected]> Committed: Thu Feb 23 15:26:14 2017 +0200 ---------------------------------------------------------------------- ambari-web/app/assets/test/tests.js | 1 + .../rangerAdmin/step3_controller.js | 54 +- .../rangerAdmin/step4_controller.js | 68 +- .../rangerAdmin/wizard_controller.js | 43 + ambari-web/app/controllers/main/host/details.js | 859 +++++++++++------- .../controllers/main/service/info/configs.js | 8 +- ambari-web/app/controllers/main/service/item.js | 118 ++- .../main/service/reassign/step1_controller.js | 78 +- .../main/service/reassign/step3_controller.js | 672 +++++++++++++++ .../main/service/reassign/step4_controller.js | 634 +------------- .../main/service/reassign_controller.js | 55 +- .../app/controllers/wizard/step7_controller.js | 24 +- ambari-web/app/messages.js | 33 +- .../mixins/common/configs/enhanced_configs.js | 5 + .../app/mixins/common/track_request_mixin.js | 6 +- .../app/mixins/main/service/groups_mapping.js | 2 +- .../app/routes/ra_high_availability_routes.js | 6 +- ambari-web/app/routes/reassign_master_routes.js | 25 +- ambari-web/app/styles/application.less | 68 +- .../modal_popups/dependent_configs_table.hbs | 20 +- .../highAvailability/journalNode/step2.hbs | 4 + .../highAvailability/rangerAdmin/step3.hbs | 7 + .../main/host/details/addComponentPopup.hbs | 19 - .../host/details/addDeleteComponentPopup.hbs | 48 ++ .../main/host/details/deleteComponentPopup.hbs | 43 - .../templates/main/service/add_host_popup.hbs | 28 - .../info/delete_service_warning_popup.hbs | 26 + .../templates/main/service/reassign/step3.hbs | 36 +- .../highAvailability/rangerAdmin/step3_view.js | 6 +- ambari-web/app/views/main/host/summary.js | 4 - .../views/main/service/reassign/step3_view.js | 4 +- .../views/main/service/reassign/step5_view.js | 4 +- .../rangerAdmin/step3_controller_test.js | 104 +++ .../test/controllers/main/host/details_test.js | 862 ++++++++++--------- .../main/service/info/config_test.js | 15 +- .../test/controllers/main/service/item_test.js | 17 +- .../service/reassign/step1_controller_test.js | 17 +- .../service/reassign/step3_controller_test.js | 634 ++++++++++++++ .../service/reassign/step4_controller_test.js | 646 +------------- .../test/controllers/wizard/step7_test.js | 18 + 40 files changed, 3062 insertions(+), 2259 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/assets/test/tests.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/assets/test/tests.js b/ambari-web/app/assets/test/tests.js index 7440819..aae27ea 100644 --- a/ambari-web/app/assets/test/tests.js +++ b/ambari-web/app/assets/test/tests.js @@ -82,6 +82,7 @@ var files = [ 'test/controllers/main/admin/highAvailability/hawq/addStandby/step3_controller_test', 'test/controllers/main/admin/highAvailability/hawq/removeStandby/step2_controller_test', 'test/controllers/main/admin/highAvailability/hawq/activateStandby/step2_controller_test', + 'test/controllers/main/admin/highAvailability/rangerAdmin/step3_controller_test', 'test/controllers/main/dashboard/config_history_controller_test', 'test/controllers/main/charts/heatmap_test', 'test/controllers/main/charts/heatmap_metrics/heatmap_metric_test', http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step3_controller.js index 475cc52..7e46810 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step3_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step3_controller.js @@ -19,6 +19,58 @@ var App = require('app'); App.RAHighAvailabilityWizardStep3Controller = Em.Controller.extend({ - name: "rAHighAvailabilityWizardStep3Controller" + name: 'rAHighAvailabilityWizardStep3Controller', + + isLoaded: false, + + versionLoaded: true, + + hideDependenciesInfoBar: true, + + stepConfigs: [ + App.ServiceConfig.create({ + serviceName: 'MISC', + showConfig: true + }) + ], + + loadStep: function () { + var self = this; + App.get('router.mainController.isLoading').call(App.get('router.clusterController'), 'isConfigsPropertiesLoaded').done(function () { + var stepConfig = self.get('stepConfigs.firstObject'), + configs = [], + configCategories = [], + installedServices = App.Service.find().mapProperty('serviceName'); + self.get('wizardController.configs').forEach(function (config) { + var service = App.config.get('serviceByConfigTypeMap')[config.siteName]; + if (service) { + var serviceName = service.get('serviceName'), + serviceDisplayName = service.get('displayName'); + if (installedServices.contains(serviceName)) { + var property = App.configsCollection.getConfigByName(config.propertyName, config.siteName) || {}; + if (!configCategories.someProperty('name'), serviceName) { + configCategories.push(App.ServiceConfigCategory.create({ + name: serviceName, + displayName: serviceDisplayName + })); + } + configs.push(App.ServiceConfigProperty.create(property, { + category: serviceName, + value: self.get('content.loadBalancerURL'), + isEditable: false + })); + } + } + }); + stepConfig.setProperties({ + configs: configs, + configCategories: configCategories + }); + self.setProperties({ + isLoaded: true, + selectedService: stepConfig + }); + }); + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step4_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step4_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step4_controller.js index b241707..df96b1f 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step4_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step4_controller.js @@ -52,18 +52,7 @@ App.RAHighAvailabilityWizardStep4Controller = App.HighAvailabilityProgressPageCo onLoadConfigsTags: function (data) { var urlParams = []; - urlParams.push('(type=admin-properties&tag=' + data.Clusters.desired_configs['admin-properties'].tag + ')'); - var siteNamesToFetch = [ - 'ranger-hdfs-security', - 'ranger-yarn-security', - 'ranger-hbase-security', - 'ranger-hive-security', - 'ranger-knox-security', - 'ranger-kafka-security', - 'ranger-kms-security', - 'ranger-storm-security', - 'ranger-atlas-security' - ]; + var siteNamesToFetch = this.get('wizardController.configs').mapProperty('siteName'); siteNamesToFetch.map(function(siteName) { if(siteName in data.Clusters.desired_configs) { urlParams.push('(type=' + siteName + '&tag=' + data.Clusters.desired_configs[siteName].tag + ')'); @@ -83,63 +72,18 @@ App.RAHighAvailabilityWizardStep4Controller = App.HighAvailabilityProgressPageCo onLoadConfigs: function (data) { var configs = []; - var self = this; - data.items.findProperty('type', 'admin-properties').properties['policymgr_external_url'] = this.get('content.loadBalancerURL'); - configs.push({ - Clusters: { - desired_config: this.reconfigureSites(['admin-properties'], data, Em.I18n.t('admin.highAvailability.step4.save.configuration.note').format(App.format.role('RANGER_ADMIN', false))) - } - }); - var configsToChange = [ - { - siteName: 'ranger-hdfs-security', - property: 'ranger.plugin.hdfs.policy.rest.url' - }, - { - siteName: 'ranger-yarn-security', - property: 'ranger.plugin.yarn.policy.rest.url' - }, - { - siteName: 'ranger-hbase-security', - property: 'ranger.plugin.hbase.policy.rest.url' - }, - { - siteName: 'ranger-hive-security', - property: 'ranger.plugin.hive.policy.rest.url' - }, - { - siteName: 'ranger-knox-security', - property: 'ranger.plugin.knox.policy.rest.url' - }, - { - siteName: 'ranger-kafka-security', - property: 'ranger.plugin.kafka.policy.rest.url' - }, - { - siteName: 'ranger-kms-security', - property: 'ranger.plugin.kms.policy.rest.url' - }, - { - siteName: 'ranger-storm-security', - property: 'ranger.plugin.storm.policy.rest.url' - }, - { - siteName: 'ranger-atlas-security', - property: 'ranger.plugin.atlas.policy.rest.url' - } - ]; - configsToChange.map(function(item) { + this.get('wizardController.configs').map(function(item) { var config = data.items.findProperty('type', item.siteName); - if(config) { - config.properties[item.property] = self.get('content.loadBalancerURL'); + if (config) { + config.properties[item.propertyName] = this.get('content.loadBalancerURL'); configs.push({ Clusters: { - desired_config: self.reconfigureSites([item.siteName], data, Em.I18n.t('admin.highAvailability.step4.save.configuration.note').format(App.format.role('RANGER_ADMIN', false))) + desired_config: this.reconfigureSites([item.siteName], data, Em.I18n.t('admin.highAvailability.step4.save.configuration.note').format(App.format.role('RANGER_ADMIN', false))) } }); } - }); + }, this); App.ajax.send({ name: 'common.service.multiConfigurations', http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js index 2bc6e37..3f4bf33 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js @@ -41,6 +41,49 @@ App.RAHighAvailabilityWizardController = App.WizardController.extend({ masterComponentHosts: null }), + configs: [ + { + siteName: 'admin-properties', + propertyName: 'policymgr_external_url' + }, + { + siteName: 'ranger-hdfs-security', + propertyName: 'ranger.plugin.hdfs.policy.rest.url' + }, + { + siteName: 'ranger-yarn-security', + propertyName: 'ranger.plugin.yarn.policy.rest.url' + }, + { + siteName: 'ranger-hbase-security', + propertyName: 'ranger.plugin.hbase.policy.rest.url' + }, + { + siteName: 'ranger-hive-security', + propertyName: 'ranger.plugin.hive.policy.rest.url' + }, + { + siteName: 'ranger-knox-security', + propertyName: 'ranger.plugin.knox.policy.rest.url' + }, + { + siteName: 'ranger-kafka-security', + propertyName: 'ranger.plugin.kafka.policy.rest.url' + }, + { + siteName: 'ranger-kms-security', + propertyName: 'ranger.plugin.kms.policy.rest.url' + }, + { + siteName: 'ranger-storm-security', + propertyName: 'ranger.plugin.storm.policy.rest.url' + }, + { + siteName: 'ranger-atlas-security', + propertyName: 'ranger.plugin.atlas.policy.rest.url' + } + ], + init: function () { this._super(); this.clearStep(); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/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 f040db5..c3b02b7 100644 --- a/ambari-web/app/controllers/main/host/details.js +++ b/ambari-web/app/controllers/main/host/details.js @@ -22,7 +22,7 @@ var hostsManagement = require('utils/hosts'); var stringUtils = require('utils/string_utils'); require('utils/configs/add_component_config_initializer'); -App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDownload, App.InstallComponent, App.InstallNewVersion, { +App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDownload, App.InstallComponent, App.InstallNewVersion, App.TrackRequestMixin, { name: 'mainHostDetailsController', @@ -39,12 +39,18 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow isFromHosts: false, /** - * Are we adding hive server2 component + * Determines whether we are adding Hive Server2 component * @type {bool} */ addHiveServer: false, /** + * Determines whether we are adding ZooKeeper Server component + * @type {bool} + */ + addZooKeeperServer: false, + + /** * path to page visited before * @type {string} */ @@ -67,6 +73,45 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow */ isOozieServerAddable: true, + isConfigsLoadingInProgress: false, + + addDeleteComponentsMap: { + 'ZOOKEEPER_SERVER': { + addPropertyName: 'addZooKeeperServer', + deletePropertyName: 'fromDeleteZkServer' + }, + 'HIVE_METASTORE': { + deletePropertyName: 'deleteHiveMetaStore', + hostPropertyName: 'hiveMetastoreHost', + configTagsCallbackName: 'loadHiveConfigs', + configsCallbackName: 'onLoadHiveConfigs' + }, + 'WEBHCAT_SERVER': { + deletePropertyName: 'deleteWebHCatServer', + hostPropertyName: 'webhcatServerHost', + configTagsCallbackName: 'loadWebHCatConfigs', + configsCallbackName: 'onLoadHiveConfigs' + }, + 'HIVE_SERVER': { + addPropertyName: 'addHiveServer', + deletePropertyName: 'deleteHiveServer', + configTagsCallbackName: 'loadHiveConfigs', + configsCallbackName: 'onLoadHiveConfigs' + }, + 'NIMBUS': { + deletePropertyName: 'deleteNimbusHost', + hostPropertyName: 'nimbusHost', + configTagsCallbackName: 'loadStormConfigs', + configsCallbackName: 'onLoadStormConfigs' + }, + 'RANGER_KMS_SERVER': { + deletePropertyName: 'deleteRangerKMSServer', + hostPropertyName: 'rangerKMSServerHost', + configTagsCallbackName: 'loadRangerConfigs', + configsCallbackName: 'onLoadRangerConfigs' + } + }, + zooKeeperRelatedServices: [ { serviceName: 'HIVE', @@ -106,6 +151,99 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow ], /** + * Determines whether adding/deleting host component requires configs changes + * @type {Boolean} + */ + 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} + */ + allPropertiesToChange: [], + + /** + * Array of editable properties affected by adding/deleting host component + * @type {Array} + */ + recommendedPropertiesToChange: [], + + /** + * Array of non-editable properties affected by adding/deleting host component + * @type {Array} + */ + requiredPropertiesToChange: [], + + /** + * Properties affected by adding/deleting host component, grouped by service, formatted for PUT call + * @type {Array} + */ + groupedPropertiesToChange: [], + + hasPropertiesToChange: Em.computed.or('recommendedPropertiesToChange.length', 'requiredPropertiesToChange.length'), + + addDeleteComponentPopupBody: Em.View.extend({ + templateName: require('templates/main/host/details/addDeleteComponentPopup'), + commonMessage: '', + manualKerberosWarning: App.get('router.mainAdminKerberosController.isManualKerberos') ? + Em.I18n.t('hosts.host.manualKerberosWarning') : '', + lastComponent: false, + lastComponentError: '', + hasHostsSelect: false, + selectedHost: null, + anyHostsWithoutComponent: true + }), + + 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 () { + this.get('recommendedPropertiesToChange').forEach(function (property) { + var value = property.saveRecommended ? property.recommendedValue : property.initialValue, + filename = property.propertyFileName; + if (this.get('groupedPropertiesToChange.length')) { + var group = this.get('groupedPropertiesToChange').find(function (item) { + return item.properties.hasOwnProperty(filename); + }); + if (group) { + group.properties[filename][property.propertyName] = value; + } + } + }, this); + }, + + /** * Open dashboard page * @method routeHome */ @@ -343,51 +481,81 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow if ($(event.target).closest('li').hasClass('disabled')) { return; } - var self = this; var component = event.context; var componentName = component.get('componentName'); var displayName = component.get('displayName'); - var isLastComponent = (this.getTotalComponent(component) === 1); + var returnFunc; + var componentsMapItem = this.get('addDeleteComponentsMap')[componentName]; + if (componentsMapItem) { + if (componentsMapItem.deletePropertyName) { + this.set(componentsMapItem.deletePropertyName, true); + } + this.clearConfigsChanges(); + this.set('isReconfigureRequired', true); + returnFunc = this.showDeleteComponentPopup(component); + } else if (componentName === 'JOURNALNODE') { + returnFunc = App.showConfirmationPopup(function () { + App.router.transitionTo('main.services.manageJournalNode'); + }, Em.I18n.t('hosts.host.deleteComponent.popup.deleteJournalNodeMsg')); + } else { + returnFunc = this.showDeleteComponentPopup(component); + } + return returnFunc; + }, + + showDeleteComponentPopup: function (component) { + var self = this, + isLastComponent = (this.getTotalComponent(component) === 1), + componentName = component.get('componentName'), + componentDisplayName = component.get('displayName'), + 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'), - primary: componentName == 'JOURNALNODE'? Em.I18n.t('ok') : Em.I18n.t('hosts.host.deleteComponent.popup.confirm'), - bodyClass: Em.View.extend({ - templateName: require('templates/main/host/details/deleteComponentPopup') + controller: self, + classNameBindings: ['controller.hasPropertiesToChange:sixty-percent-width-modal', 'controller.hasPropertiesToChange:modal-full-width'], + primary: Em.I18n.t('hosts.host.deleteComponent.popup.confirm'), + bodyClass: self.get('addDeleteComponentPopupBody').extend({ + commonMessage: commonMessage, + recommendedPropertiesToChange: self.get('recommendedPropertiesToChange'), + requiredPropertiesToChange: self.get('requiredPropertiesToChange'), + lastComponentError: Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(componentDisplayName), + lastComponent: function () { + this.set('parentView.isChecked', !isLastComponent); + return isLastComponent; + }.property() }), - isHiveMetastore: componentName == 'HIVE_METASTORE', - isWebHCatServer: componentName == 'WEBHCAT_SERVER', - isNimbus: componentName == 'NIMBUS', - isRangerKMSServer: componentName == 'RANGER_KMS_SERVER', - isZkServer: componentName == 'ZOOKEEPER_SERVER', - isJournalNode: componentName == 'JOURNALNODE', - - deleteHiveMetastoreMsg: Em.I18n.t('hosts.host.deleteComponent.popup.deleteHiveMetastore'), - deleteWebHCatServerMsg: Em.I18n.t('hosts.host.deleteComponent.popup.deleteWebHCatServer'), - deleteNimbusMsg: Em.I18n.t('hosts.host.deleteComponent.popup.deleteNimbus'), - deleteRangerKMSServereMsg: Em.I18n.t('hosts.host.deleteComponent.popup.deleteRangerKMSServer'), - lastComponentError: Em.I18n.t('hosts.host.deleteComponent.popup.warning').format(displayName), - deleteComponentMsg: Em.I18n.t('hosts.host.deleteComponent.popup.msg1').format(displayName), - deleteZkServerMsg: Em.I18n.t('hosts.host.deleteComponent.popup.deleteZooKeeperServer'), - deleteJournalNodeMsg: Em.I18n.t('hosts.host.deleteComponent.popup.deleteJournalNodeMsg'), - isChecked: false, - disablePrimary: Em.computed.not('isChecked'), - lastComponent: function () { - this.set('isChecked', !isLastComponent); - return isLastComponent; - }.property(), - + disablePrimary: function () { + return (this.get('controller.isReconfigureRequired') && this.get('controller.isConfigsLoadingInProgress')) || !this.get('isChecked'); + }.property('controller.isReconfigureRequired', 'controller.isConfigsLoadingInProgress', 'isChecked'), onPrimary: function () { - var popup = this; - if (componentName == 'JOURNALNODE') { - popup.hide(); - App.router.transitionTo('main.services.manageJournalNode'); - } else { - self._doDeleteHostComponent(component, function () { - self.set('redrawComponents', true); - popup.hide(); - }); + this._super(); + if (self.get('isReconfigureRequired')) { + self.applyConfigsCustomization(); } + self._doDeleteHostComponent(componentName, function () { + if (self.get('isReconfigureRequired')) { + self.saveConfigsBatch(self.get('groupedPropertiesToChange'), componentName); + self.clearConfigsChanges(); + } + self.set('redrawComponents', true); + }); + }, + onSecondary: function () { + this._super(); + self.clearConfigsChanges(); + }, + onClose: function () { + this._super(); + self.clearConfigsChanges(); } }); }, @@ -425,13 +593,13 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow * when components failed to get deleted. * @method _doDeleteHostComponent */ - _doDeleteHostComponent: function (component, callback) { + _doDeleteHostComponent: function (componentName, callback) { callback = callback || Em.K; App.ajax.send({ - name: (Em.isNone(component)) ? 'common.delete.host' : 'common.delete.host_component', + name: (Em.isNone(componentName)) ? 'common.delete.host' : 'common.delete.host_component', sender: this, data: { - componentName: (component) ? component.get('componentName') : '', + componentName: componentName || '', hostName: this.get('content.hostName') }, success: '_doDeleteHostComponentSuccessCallback', @@ -450,31 +618,8 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow * @method _doDeleteHostComponentSuccessCallback */ _doDeleteHostComponentSuccessCallback: function (response, request, data) { - var self = this; this.set('_deletedHostComponentResult', null); this.removeHostComponentModel(data.componentName, data.hostName); - if (data.componentName == 'ZOOKEEPER_SERVER') { - this.set('fromDeleteZkServer', true); - this.updateStormConfigs(); - self.isServiceMetricsLoaded(function () { - self.loadConfigs(); - }); - } else if (data.componentName == 'HIVE_METASTORE') { - this.set('deleteHiveMetaStore', true); - this.loadConfigs('loadHiveConfigs'); - } else if (data.componentName == 'WEBHCAT_SERVER') { - this.set('deleteWebHCatServer', true); - this.loadConfigs('loadWebHCatConfigs'); - } else if (data.componentName == 'HIVE_SERVER') { - this.set('deleteHiveServer', true); - this.loadConfigs('loadHiveConfigs'); - } else if (data.componentName == 'NIMBUS') { - this.set('deleteNimbusHost', true); - this.loadConfigs('loadStormConfigs'); - } else if (data.componentName == 'RANGER_KMS_SERVER') { - this.set('deleteRangerKMSServer', true); - this.loadConfigs('loadRangerConfigs'); - } }, /** @@ -591,14 +736,16 @@ 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') }), isManualKerberos = App.get('router.mainAdminKerberosController.isManualKerberos'), - manualKerberosWarning = isManualKerberos ? Em.I18n.t('hosts.host.manualKerberosWarning') : ''; + manualKerberosWarning = isManualKerberos ? Em.I18n.t('hosts.host.manualKerberosWarning') : '', + componentsMapItem = this.get('addDeleteComponentsMap')[componentName]; if (!!missedComponents.length) { var popupMessage = Em.I18n.t('host.host.addComponent.popup.dependedComponents.body').format(component.get('displayName'), @@ -608,106 +755,139 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow return App.showAlertPopup(Em.I18n.t('host.host.addComponent.popup.dependedComponents.header'), popupMessage); } - switch (componentName) { - case 'ZOOKEEPER_SERVER': - returnFunc = App.showConfirmationPopup(function () { - self.installHostComponentCall(self.get('content.hostName'), component) - }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); - break; - case 'HIVE_METASTORE': - returnFunc = App.showConfirmationPopup(function () { - self.set('hiveMetastoreHost', hostName); - self.loadConfigs("loadHiveConfigs"); - }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); - break; - case 'WEBHCAT_SERVER': - returnFunc = App.showConfirmationPopup(function () { - self.set('webhcatServerHost', hostName); - self.loadConfigs("loadWebHCatConfigs"); - }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); - break; - case 'NIMBUS': - returnFunc = App.showConfirmationPopup(function () { - self.set('nimbusHost', hostName); - self.loadConfigs("loadStormConfigs"); - }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); - break; - case 'RANGER_KMS_SERVER': - returnFunc = App.showConfirmationPopup(function () { - self.set('rangerKMSServerHost', hostName); - self.loadConfigs("loadRangerConfigs"); - }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); - break; - case 'JOURNALNODE': - returnFunc = App.showConfirmationPopup(function () { - App.router.transitionTo('main.services.manageJournalNode'); - }, Em.I18n.t('hosts.host.addComponent.' + componentName) + manualKerberosWarning); - break; - default: - returnFunc = this.addClientComponent(component, isManualKerberos); + if (componentsMapItem) { + var primary; + if (componentsMapItem.hostPropertyName) { + this.set(componentsMapItem.hostPropertyName, hostName); + } + if (componentsMapItem.addPropertyName) { + this.set(componentsMapItem.addPropertyName, true); + primary = function () { + this.set(componentsMapItem.addPropertyName, false); + }; + } + this.clearConfigsChanges(); + this.set('isReconfigureRequired', true); + 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; }, - /** - * Send command to server to install client on selected host - * @param {App.HostComponent} component - * @param {boolean} isManualKerberos - * @returns {*} - */ - addClientComponent: function (component, isManualKerberos) { + showAddComponentPopup: function (component, hostName, primary, primaryOnReconfigure, hasHostsSelect) { var self = this, - displayName = this.formatClientsMessage(component); - - return this.showAddComponentPopup(displayName, isManualKerberos, function () { - self.installHostComponentCall(self.get('content.hostName'), component); - }); - }, - - /** - * - * @param {string} displayName - * @param {boolean} isManualKerberos - * @param {Function} primary - * @returns {*} - */ - showAddComponentPopup: function (displayName, isManualKerberos, primary) { - isManualKerberos = isManualKerberos || false; - + componentName = component.get('componentName'), + componentDisplayName = component.get('displayName'), + 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({ - primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'), header: Em.I18n.t('popup.confirmation.commonHeader'), - - addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(displayName), - - manualKerberosWarning: isManualKerberos ? Em.I18n.t('hosts.host.manualKerberosWarning') : '', - - bodyClass: Em.View.extend({ - templateName: require('templates/main/host/details/addComponentPopup') + controller: self, + classNameBindings: ['controller.hasPropertiesToChange:sixty-percent-width-modal', 'controller.hasPropertiesToChange:modal-full-width'], + primary: Em.I18n.t('hosts.host.addComponent.popup.confirm'), + bodyClass: self.get('addDeleteComponentPopupBody').extend({ + 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 () { - this.hide(); - primary(); + this._super(); + if (self.get('isReconfigureRequired')) { + self.applyConfigsCustomization(); + self.saveConfigsBatch(self.get('groupedPropertiesToChange'), componentName, hostName); + if (primaryOnReconfigure) { + primaryOnReconfigure.call(self); + } + self.clearConfigsChanges(); + } else if (primary) { + primary(); + } + }, + onSecondary: function () { + this._super(); + self.clearConfigsChanges(); + }, + onClose: function () { + this._super(); + self.clearConfigsChanges(); } }); }, - /** - * format message for operation of adding clients - * @param client - */ - formatClientsMessage: function (client) { - var displayName = Em.isNone(client.get('displayName')) ? '' : client.get('displayName'); - var subComponentNames = client.get('subComponentNames'); - if (subComponentNames && subComponentNames.length > 0) { - var dns = []; - subComponentNames.forEach(function (scn) { - dns.push(App.format.role(scn, false)); + loadComponentRelatedConfigs: function (configTagsCallbackName, configsCallbackName) { + var self = this; + if (this.get('isReconfigureRequired')) { + this.set('isConfigsLoadingInProgress', true); + this.isServiceMetricsLoaded(function () { + self.loadConfigs(configTagsCallbackName, configsCallbackName); }); - displayName += " (" + dns.join(", ") + ")"; } - return displayName; }, /** @@ -727,17 +907,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow this.mimicWorkStatusChange(params.component, App.HostComponentStatus.installing, App.HostComponentStatus.stopped); } - this.showBackgroundOperationsPopup(function () { - if (params.componentName === 'ZOOKEEPER_SERVER' || params.componentName === 'HIVE_SERVER') { - self.set(params.componentName === 'ZOOKEEPER_SERVER' ? 'zkRequestId' : 'hiveRequestId', data.Requests.id); - self.addObserver( - 'App.router.backgroundOperationsController.serviceTimestamp', - self, - (params.componentName === 'ZOOKEEPER_SERVER' ? self.checkZkConfigs : self.checkHiveDone) - ); - params.componentName === 'ZOOKEEPER_SERVER' ? self.checkZkConfigs() : self.checkHiveDone(); - } - }); + this.showBackgroundOperationsPopup(); return true; }, @@ -753,22 +923,6 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow }, /** - * Call load tags - * @method checkHiveDone - */ - checkHiveDone: function () { - var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('hiveRequestId')); - if (bg && !bg.get('isRunning')) { - var self = this; - this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkHiveDone); - setTimeout(function () { - self.set('addHiveServer', true); - self.loadConfigs("loadHiveConfigs"); - }, App.get('componentsUpdateInterval')); - } - }, - - /** * Success callback for load configs request * @param {object} data * @method loadOozieConfigs @@ -788,7 +942,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * get Oozie database config and set databaseType * @param {object} data - * @method onLoadHiveConfigs + * @method onLoadOozieConfigs */ onLoadOozieConfigs: function (data) { var configs = {}; @@ -803,17 +957,20 @@ 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) { - App.ajax.send({ + 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); }, /** @@ -829,6 +986,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow var hostComponentsTopology = { masterComponentHosts: [] }; + var propertiesToChange = this.get('allPropertiesToChange'); var masterComponents = this.bootstrapHostsMapping('ZOOKEEPER_SERVER'); if (this.get('fromDeleteHost') || this.get('fromDeleteZkServer')) { this.set('fromDeleteHost', false); @@ -837,6 +995,13 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow if (!Em.isNone(removedHost)) { Em.set(removedHost, 'isInstalled', false); } + } else if (this.get('addZooKeeperServer')) { + this.set('addZooKeeperServer', false); + masterComponents.push({ + component: 'ZOOKEEPER_SERVER', + hostName: this.get('content.hostName'), + isInstalled: true + }); } var dependencies = { zkClientPort: zkPort, @@ -846,15 +1011,26 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow Em.keys(configs).forEach(function(fileName) { var properties = configs[fileName]; Em.keys(properties).forEach(function(propertyName) { - var propertyDef = { - fileName: fileName, - name: propertyName, - value: properties[propertyName] - }; - var configProperty = initializer.initialValue(propertyDef, hostComponentsTopology, dependencies); + var currentValue = properties[propertyName], + propertyDef = { + fileName: fileName, + name: propertyName, + value: currentValue + }, + configProperty = initializer.initialValue(propertyDef, hostComponentsTopology, dependencies); initializer.updateSiteObj(configs[fileName], configProperty); - }); - }); + if (this.get('isReconfigureRequired') && currentValue !== configs[fileName][propertyName]) { + var service = App.config.get('serviceByConfigTypeMap')[fileName]; + propertiesToChange.pushObject({ + propertyFileName: fileName, + propertyName: propertyName, + serviceDisplayName: service && service.get('displayName'), + initialValue: currentValue, + recommendedValue: propertyDef.value + }); + } + }, this); + }, this); }, /** @@ -885,8 +1061,10 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow var nimbusHost = this.get('nimbusHost'), stormNimbusHosts = this.getStormNimbusHosts(), configs = {}, - attributes = {}; + attributes = {}, + propertiesToChange = this.get('allPropertiesToChange'); + this.saveLoadedConfigs(data); data.items.forEach(function (item) { configs[item.type] = item.properties; attributes[item.type] = item.properties_attributes || {}; @@ -894,7 +1072,19 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow this.updateZkConfigs(configs); - configs['storm-site']['nimbus.seeds'] = JSON.stringify(stormNimbusHosts).replace(/"/g, "'"); + var nimbusSeedsInit = configs['storm-site']['nimbus.seeds'], + nimbusSeedsRecommended = JSON.stringify(stormNimbusHosts).replace(/"/g, "'"); + configs['storm-site']['nimbus.seeds'] = nimbusSeedsRecommended; + if (this.get('isReconfigureRequired') && nimbusSeedsInit !== nimbusSeedsRecommended) { + var service = App.config.get('serviceByConfigTypeMap')['storm-site']; + propertiesToChange.pushObject({ + propertyFileName: 'storm-site', + propertyName: 'nimbus.seeds', + serviceDisplayName: service && service.get('displayName'), + initialValue: nimbusSeedsInit, + recommendedValue: nimbusSeedsRecommended + }); + } var groups = [ { properties: { @@ -905,16 +1095,22 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow } } ]; - this.saveConfigsBatch(groups, 'NIMBUS', nimbusHost); + if (this.get('isReconfigureRequired')) { + this.setConfigsChanges(groups); + } else { + this.saveConfigsBatch(groups, 'NIMBUS', nimbusHost); + } }, /** * Success callback for load configs request * @param {object} data - * @method loadHiveConfigs + * @param {object} opt + * @param {object} params + * @method loadWebHCatConfigs */ - loadWebHCatConfigs: function (data) { - return App.ajax.send({ + loadWebHCatConfigs: function (data, opt, params) { + var request = App.ajax.send({ name: 'admin.get.all_configurations', sender: this, data: { @@ -926,17 +1122,21 @@ 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; }, /** * Success callback for load configs request * @param {object} data + * @param {object} opt + * @param {object} params * @method loadHiveConfigs */ - loadHiveConfigs: function (data) { - return App.ajax.send({ + loadHiveConfigs: function (data, opt, params) { + var request = App.ajax.send({ name: 'admin.get.all_configurations', sender: this, data: { @@ -947,8 +1147,10 @@ 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; }, /** @@ -972,11 +1174,15 @@ 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 || {}; }, this); - + var propertiesToChange = this.get('allPropertiesToChange'); port = configs['hive-site']['hive.metastore.uris'].match(/:[0-9]{2,4}/); port = port ? port[0].slice(1) : "9083"; @@ -994,16 +1200,27 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow ['hive-site', 'webhcat-site', 'hive-env', 'core-site'].forEach(function(fileName) { if (configs[fileName]) { Em.keys(configs[fileName]).forEach(function(propertyName) { - var propertyDef = { + var currentValue = configs[fileName][propertyName], + propertyDef = { fileName: fileName, name: propertyName, - value: configs[fileName][propertyName] + value: currentValue }, configProperty = initializer.initialValue(propertyDef, localDB, dependencies); initializer.updateSiteObj(configs[fileName], configProperty); - }); + if (this.get('isReconfigureRequired') && currentValue !== configs[fileName][propertyName]) { + var service = App.config.get('serviceByConfigTypeMap')[fileName]; + propertiesToChange.pushObject({ + propertyFileName: fileName, + propertyName: propertyName, + serviceDisplayName: service && service.get('displayName'), + initialValue: currentValue, + recommendedValue: propertyDef.value + }); + } + }, this); } - }); + }, this); initializer.cleanup(); @@ -1029,12 +1246,16 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow } } ]; - var params = [groups]; - var componentName = this.get('addHiveServer') ? 'HIVE_SERVER' : (hiveMetastoreHost ? 'HIVE_METASTORE' : 'WEBHCAT_SERVER'); - var host = webhcatServerHost || hiveMetastoreHost; - params.pushObjects([componentName, host]); - this.saveConfigsBatch.apply(this, params); - this.set('addHiveServer', false); + if (this.get('isReconfigureRequired')) { + this.setConfigsChanges(groups); + } else { + var args = [groups]; + var componentName = this.get('addHiveServer') ? 'HIVE_SERVER' : (hiveMetastoreHost ? 'HIVE_METASTORE' : 'WEBHCAT_SERVER'); + var host = webhcatServerHost || hiveMetastoreHost; + args.pushObjects([componentName, host]); + this.saveConfigsBatch.apply(this, args); + this.set('addHiveServer', false); + } }, /** @@ -1044,36 +1265,48 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow * @param host */ saveConfigsBatch: function (groups, componentName, host) { - groups.forEach(function (group) { - var desiredConfigs = [], - tag = 'version' + (new Date).getTime(), - properties = group.properties; - - for (var site in properties) { - if (!properties.hasOwnProperty(site) || Em.isNone(properties[site])) continue; - desiredConfigs.push({ - "type": site, - "tag": tag, - "properties": properties[site], - "properties_attributes": group.properties_attributes[site], - "service_config_version_note": Em.I18n.t('hosts.host.configs.save.note').format(App.format.role(componentName, false)) - }); - } - if (desiredConfigs.length > 0) { - App.ajax.send({ - name: 'common.service.configurations', - sender: this, - data: { - desired_config: desiredConfigs, + if (groups.length) { + groups.forEach(function (group) { + var desiredConfigs = [], + tag = 'version' + (new Date).getTime(), + properties = group.properties; + + for (var site in properties) { + if (!properties.hasOwnProperty(site) || Em.isNone(properties[site])) continue; + desiredConfigs.push({ + "type": site, + "tag": tag, + "properties": properties[site], + "properties_attributes": group.properties_attributes[site], + "service_config_version_note": Em.I18n.t('hosts.host.configs.save.note').format(App.format.role(componentName, false)) + }); + } + if (desiredConfigs.length > 0) { + App.ajax.send({ + name: 'common.service.configurations', + sender: this, + data: { + desired_config: desiredConfigs, + componentName: componentName, + host: host + }, + success: 'installHostComponent' + }); + } else { + this.installHostComponent(null, null, { componentName: componentName, host: host - }, - success: 'installHostComponent' - }); - } - //clear hive metastore host not to send second request to install component - host = null; - }, this); + }); + } + //clear hive metastore host not to send second request to install component + host = null; + }, this); + } else { + this.installHostComponent(null, null, { + componentName: componentName, + host: host + }); + } }, /** @@ -1150,23 +1383,26 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * Success callback for load configs request * @param {object} data - * @method loadHiveConfigs + * @param {object} opt + * @param {object} params + * @method loadRangerConfigs */ - loadRangerConfigs: function (data) { - App.ajax.send({ + 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); }, /** * update and save Hive hive.metastore.uris config to server * @param {object} data - * @method onLoadHiveConfigs + * @method onLoadRangerConfigs */ onLoadRangerConfigs: function (data) { var properties = [ @@ -1196,20 +1432,37 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow 'hdfs-site': hdfsSiteConfigs.properties_attributes } } - ]; + ], + propertiesToChange = this.get('allPropertiesToChange'); + + this.saveLoadedConfigs(data); properties.forEach(function (property) { var typeConfigs = data.items.findProperty('type', property.type).properties, - currentValue = typeConfigs[property.name], - pattern = new RegExp('^kms:\\/\\/http@(.+):' + rkmsPort + '\\/kms$'), - patternMatch = currentValue && currentValue.match(pattern), - currentHostsList = patternMatch && patternMatch[1].split(';').sort().join(';'); + currentValue = typeConfigs[property.name], + pattern = new RegExp('^kms:\\/\\/http@(.+):' + rkmsPort + '\\/kms$'), + patternMatch = currentValue && currentValue.match(pattern), + currentHostsList = patternMatch && patternMatch[1].split(';').sort().join(';'); if (currentHostsList !== rkmsHosts) { typeConfigs[property.name] = newValue; + if (this.get('isReconfigureRequired')) { + var service = App.config.get('serviceByConfigTypeMap')[property.type]; + propertiesToChange.pushObject({ + propertyFileName: property.type, + propertyName: property.name, + serviceDisplayName: service && service.get('displayName'), + initialValue: currentValue, + recommendedValue: newValue, + saveRecommended: true + }); + } } - }); - - this.saveConfigsBatch(groups, 'RANGER_KMS_SERVER', hostToInstall); + }, this); + if (this.get('isReconfigureRequired')) { + this.setConfigsChanges(groups); + } else { + this.saveConfigsBatch(groups, 'RANGER_KMS_SERVER', hostToInstall); + } }, /** @@ -1307,47 +1560,22 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow }, /** - * Update storm config - * @method updateStormConfigs - */ - updateStormConfigs: function () { - if (App.Service.find('STORM').get('isLoaded') && App.get('isHadoop23Stack')) { - this.loadConfigs("loadStormConfigs"); - } - }, - - /** - * Load tags - * @method checkZkConfigs - */ - checkZkConfigs: function () { - var bg = App.router.get('backgroundOperationsController.services').findProperty('id', this.get('zkRequestId')); - if (bg && !bg.get('isRunning')) { - var self = this; - this.removeObserver('App.router.backgroundOperationsController.serviceTimestamp', this, this.checkZkConfigs); - setTimeout(function () { - self.updateStormConfigs(); - var callback = function () { - self.loadConfigs(); - }; - self.isServiceMetricsLoaded(callback); - }, App.get('componentsUpdateInterval')); - } - }, - - /** * Load configs * This function when used without a callback should be always used from successcallback function of the promise `App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isServiceContentFullyLoaded').done(promise)` * This is required to make sure that service metrics API determining the HA state of components is loaded * @method loadConfigs */ - loadConfigs: function (callback) { - App.ajax.send({ + 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); }, /** @@ -1361,21 +1589,25 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow /** * Success callback for load configs request * @param {object} data - * @method adConfigsSuccessCallback + * @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) { - App.ajax.send({ + var request = App.ajax.send({ name: 'reassign.load_configs', sender: this, data: { urlParams: urlParams.join('|') }, - success: 'saveZkConfigs' + success: params.callback || 'saveZkConfigs' }); + this.trackRequest(request); return true; } + this.set('isConfigsLoadingInProgress', false); return false; }, @@ -1410,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 || {}; @@ -1431,7 +1664,11 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow groups.push(group); } }); - this.saveConfigsBatch(groups, 'ZOOKEEPER_SERVER'); + if (this.get('isReconfigureRequired')) { + this.setConfigsChanges(groups); + } else { + this.saveConfigsBatch(groups, 'ZOOKEEPER_SERVER'); + } }, /** @@ -2258,7 +2495,7 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow allComponents.forEach(function (component, index) { var length = allComponents.get('length'); if (!deleteError) { - this._doDeleteHostComponent(component, function () { + this._doDeleteHostComponent(component.get('componentName'), function () { deleteError = self.get('_deletedHostComponentResult'); if (index == length - 1) { dfd.resolve(); @@ -2290,7 +2527,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'); }); @@ -2301,7 +2537,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); @@ -2433,9 +2669,11 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow } }; if (clientsToAdd.length) { - var message = stringUtils.getFormattedStringFromArray(clientsToAdd.mapProperty('displayName')); - var isManualKerberos = App.get('router.mainAdminKerberosController.isManualKerberos'); - self.showAddComponentPopup(message, isManualKerberos, function () { + var message = stringUtils.getFormattedStringFromArray(clientsToAdd.mapProperty('displayName')), + componentObject = Em.Object.create({ + displayName: message + }); + self.showAddComponentPopup(componentObject, self.get('content.hostName'), function () { sendInstallCommand(); clientsToAdd.forEach(function (component) { self.installHostComponentCall(self.get('content.hostName'), component); @@ -2535,5 +2773,34 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow */ isServiceMetricsLoaded: function(callback) { App.router.get('mainController').isLoading.call(App.router.get('clusterController'), 'isServiceContentFullyLoaded').done(callback); + }, + + setConfigsChangesForDisplay: function () { + if (App.get('router.clusterController.isConfigsPropertiesLoaded')) { + this.get('allPropertiesToChange').forEach(function (property) { + var stackProperty = App.configsCollection.getConfigByName(property.propertyName, property.propertyFileName); + if (stackProperty && (!stackProperty.isEditable || !stackProperty.isReconfigurable)) { + this.get('requiredPropertiesToChange').pushObject(property); + } else { + Em.set(property, 'saveRecommended', true); + this.get('recommendedPropertiesToChange').pushObject(property); + } + }, this); + this.set('isConfigsLoadingInProgress', false); + this.removeObserver('App.router.clusterController.isConfigsPropertiesLoaded', this, 'setConfigsChangesForDisplay'); + } + }, + + setConfigsChanges: function (groups) { + this.get('groupedPropertiesToChange').pushObjects(groups); + if (this.get('allPropertiesToChange.length')) { + if (App.get('router.clusterController.isConfigsPropertiesLoaded')) { + this.setConfigsChangesForDisplay(); + } else { + this.addObserver('App.router.clusterController.isConfigsPropertiesLoaded', this, 'setConfigsChangesForDisplay'); + } + } else { + this.set('isConfigsLoadingInProgress', false); + } } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/controllers/main/service/info/configs.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/info/configs.js b/ambari-web/app/controllers/main/service/info/configs.js index 32062e8..786c6f9 100644 --- a/ambari-web/app/controllers/main/service/info/configs.js +++ b/ambari-web/app/controllers/main/service/info/configs.js @@ -21,7 +21,7 @@ var batchUtils = require('utils/batch_scheduled_requests'); App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfigs, App.ConfigsLoader, App.ServerValidatorMixin, App.EnhancedConfigsMixin, App.ThemesMappingMixin, App.ConfigsSaverMixin, - App.ConfigsComparator, App.ComponentActionsByConfigs, App.TrackRequestMixin, { + App.ConfigsComparator, App.ComponentActionsByConfigs, { name: 'mainServiceInfoConfigsController', @@ -239,8 +239,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfi App.set('componentToBeDeleted', {}); this.clearLoadInfo(); this.clearSaveInfo(); - this.clearRecommendationsInfo(); - this.clearAllRecommendations(); + this.clearRecommendations(); this.setProperties({ saveInProgress: false, isInit: true, @@ -679,8 +678,7 @@ App.MainServiceInfoConfigsController = Em.Controller.extend(App.AddSecurityConfi */ doCancel: function () { this.set('preSelectedConfigVersion', null); - this.clearAllRecommendations(); - this.clearRecommendationsInfo(); + this.clearRecommendations(); this.loadSelectedVersion(this.get('selectedVersion'), this.get('selectedConfigGroup')); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/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 11df45a..7d67322 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/ambari-web/app/controllers/main/service/item.js @@ -21,7 +21,7 @@ var batchUtils = require('utils/batch_scheduled_requests'); var blueprintUtils = require('utils/blueprint'); var stringUtils = require('utils/string_utils'); -App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDownload, App.InstallComponent, App.ConfigsSaverMixin, App.EnhancedConfigsMixin, { +App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDownload, App.InstallComponent, App.ConfigsSaverMixin, App.EnhancedConfigsMixin, App.GroupsMappingMixin, { name: 'mainServiceItemController', /** @@ -86,6 +86,8 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow deleteServiceProgressPopup: null, + isRecommendationInProgress: false, + isClientsOnlyService: function() { return App.get('services.clientOnly').contains(this.get('content.serviceName')); }.property('content.serviceName'), @@ -939,63 +941,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 } - }); + ); }); }, @@ -1337,17 +1291,48 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow showLastWarning: function (serviceName, interDependentServices, dependentServicesToDeleteFmt) { var self = this, displayName = App.format.role(serviceName, true), - popupHeader = Em.I18n.t('services.service.delete.popup.header'); - - return App.showConfirmationPopup( - function() {self.confirmDeleteService(serviceName, interDependentServices, dependentServicesToDeleteFmt)}, - Em.I18n.t('services.service.delete.popup.warning').format(displayName) + - (interDependentServices.length ? Em.I18n.t('services.service.delete.popup.warning.dependent').format(dependentServicesToDeleteFmt) : ''), - null, - popupHeader, - Em.I18n.t('common.delete'), - true - ); + popupHeader = Em.I18n.t('services.service.delete.popup.header'), + popupPrimary = Em.I18n.t('common.delete'), + warningMessage = Em.I18n.t('services.service.delete.popup.warning').format(displayName) + + (interDependentServices.length ? Em.I18n.t('services.service.delete.popup.warning.dependent').format(dependentServicesToDeleteFmt) : ''), + callback = this.loadConfigRecommendations.bind(this, null, function () { + var serviceNames = self.get('changedProperties').mapProperty('serviceName').uniq(); + self.loadConfigGroups(serviceNames).done(function () { + self.set('isRecommendationInProgress', false); + }) + }); + this.clearRecommendations(); + this.setProperties({ + isRecommendationInProgress: true, + selectedConfigGroup: Em.Object.create({ + isDefault: true + }) + }); + App.get('router.mainController.isLoading').call(this, 'isServiceConfigsLoaded').done(callback); + return App.ModalPopup.show({ + controller: self, + header: popupHeader, + primary: popupPrimary, + primaryClass: 'btn-danger', + disablePrimary: Em.computed.alias('controller.isRecommendationInProgress'), + classNameBindings: ['controller.changedProperties.length:sixty-percent-width-modal', 'controller.changedProperties.length:modal-full-width'], + bodyClass: Em.View.extend({ + templateName: require('templates/main/service/info/delete_service_warning_popup'), + warningMessage: new Em.Handlebars.SafeString(warningMessage) + }), + onPrimary: function () { + self.confirmDeleteService(serviceName, interDependentServices, dependentServicesToDeleteFmt); + this._super(); + }, + onSecondary: function () { + self.clearRecommendations(); + this._super(); + }, + onClose: function () { + self.clearRecommendations(); + this._super(); + } + }); }, /** @@ -1589,8 +1574,7 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow if (params.servicesToDeleteNext) { this.deleteServiceCall(params.servicesToDeleteNext); } else { - var callback = this.loadConfigRecommendations.bind(this, null, this.saveConfigs.bind(this)); - App.get('router.mainController.isLoading').call(this, 'isServiceConfigsLoaded').done(callback); + this.saveConfigs(); } }, http://git-wip-us.apache.org/repos/asf/ambari/blob/304bd060/ambari-web/app/controllers/main/service/reassign/step1_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/service/reassign/step1_controller.js b/ambari-web/app/controllers/main/service/reassign/step1_controller.js index 9f30bb7..c631e85 100644 --- a/ambari-web/app/controllers/main/service/reassign/step1_controller.js +++ b/ambari-web/app/controllers/main/service/reassign/step1_controller.js @@ -26,9 +26,18 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({ * @type {object} */ dbPropertyMap: { - 'HIVE_SERVER': 'javax.jdo.option.ConnectionDriverName', - 'HIVE_METASTORE': 'javax.jdo.option.ConnectionDriverName', - 'OOZIE_SERVER': 'oozie.service.JPAService.jdbc.driver' + 'HIVE_SERVER': { + type: 'hive-site', + name: 'javax.jdo.option.ConnectionDriverName' + }, + 'HIVE_METASTORE': { + type: 'hive-site', + name: 'javax.jdo.option.ConnectionDriverName' + }, + 'OOZIE_SERVER': { + type: 'oozie-site', + name: 'oozie.service.JPAService.jdbc.driver' + } }, loadConfigsTags: function () { @@ -79,55 +88,78 @@ App.ReassignMasterWizardStep1Controller = Em.Controller.extend({ }, onLoadConfigs: function (data) { - var databaseProperty = null, - databaseType = null, - properties = {}, - isRemoteDB = null; + var databaseProperty, + databaseType = null, + databaseTypeMatch, + properties = {}, + configs = {}, + dbPropertyMapItem = Em.getWithDefault(this.get('dbPropertyMap'), this.get('content.reassign.component_name'), null), + serviceDbProp = this.get('content.reassign.service_id').toLowerCase() + '_database'; data.items.forEach(function(item) { - $.extend(properties, item.properties); + configs[item.type] = item.properties; }); - this.set('content.serviceProperties', properties); + this.get('content').setProperties({ + serviceProperties: properties, + configs: configs + }); - databaseProperty = properties[ Em.getWithDefault(this.get('dbPropertyMap'), this.get('content.reassign.component_name'), null) ]; - databaseType = databaseProperty.match(/MySQL|PostgreS|Oracle|Derby|MSSQL|Anywhere/gi)[0]; + if (dbPropertyMapItem) { + databaseProperty = Em.getWithDefault(configs, dbPropertyMapItem.type, {})[dbPropertyMapItem.name]; + databaseTypeMatch = databaseProperty && databaseProperty.match(/MySQL|PostgreS|Oracle|Derby|MSSQL|Anywhere/gi); + if (databaseTypeMatch) { + databaseType = databaseTypeMatch[0]; + } + } this.set('databaseType', databaseType); if (this.get('content.reassign.component_name') == 'OOZIE_SERVER' && databaseType !== 'derby') { App.router.reassignMasterController.set('content.hasManualSteps', false); } - var serviceDbProp = this.get('content.reassign.service_id').toLowerCase() + "_database"; - properties['is_remote_db'] = /Existing/ig.test( properties[serviceDbProp] ); + properties['is_remote_db'] = /Existing/ig.test(properties[serviceDbProp]); properties['database_hostname'] = this.getDatabaseHost(); this.saveDatabaseType(databaseType); this.saveServiceProperties(properties); + this.saveConfigs(configs); }, saveDatabaseType: function(type) { - if(type) { + if (type) { App.router.get(this.get('content.controllerName')).saveDatabaseType(type); } }, saveServiceProperties: function(properties) { - if(properties) { + if (properties) { App.router.get(this.get('content.controllerName')).saveServiceProperties(properties); } }, + saveConfigs: function(configs) { + if (configs) { + App.router.get(this.get('content.controllerName')).saveConfigs(configs); + } + }, + getDatabaseHost: function() { - var db_type = this.get('databaseType'); - var connectionURLPRops = { - 'HIVE': 'javax.jdo.option.ConnectionURL', - 'OOZIE': 'oozie.service.JPAService.jdbc.url' - }; - - var service = this.get('content.reassign.service_id'); - var connectionURL = this.get('content.serviceProperties')[connectionURLPRops[service]]; + var db_type = this.get('databaseType'), + connectionURLProps = { + 'HIVE': { + type: 'hive-site', + name: 'javax.jdo.option.ConnectionURL' + }, + 'OOZIE': { + type: 'oozie-site', + name: 'oozie.service.JPAService.jdbc.url' + } + }, + service = this.get('content.reassign.service_id'), + connectionURLPropsItem = connectionURLProps[service], + connectionURL = Em.getWithDefault(this.get('content.configs'), connectionURLPropsItem.type, {})[connectionURLPropsItem.name]; connectionURL = connectionURL.replace("jdbc:" + db_type + "://", ""); connectionURL = connectionURL.replace("/hive?createDatabaseIfNotExist=true", "");
