Repository: ambari Updated Branches: refs/heads/branch-dev-patch-upgrade fc402ebc5 -> abc961a13
AMBARI-14724. Provide option to +Add Oozie Server in Service Actions menu (akovalenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8b7aa920 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8b7aa920 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8b7aa920 Branch: refs/heads/branch-dev-patch-upgrade Commit: 8b7aa920bb7d34361e4b2ee2059c547fe01ca238 Parents: a7a9796 Author: Aleksandr Kovalenko <akovale...@hortonworks.com> Authored: Tue Jan 19 18:34:08 2016 +0200 Committer: Aleksandr Kovalenko <akovale...@hortonworks.com> Committed: Wed Jan 20 19:00:23 2016 +0200 ---------------------------------------------------------------------- ambari-web/app/controllers/main/service/item.js | 176 +++++++++++-------- .../app/mixins/common/configs/configs_saver.js | 4 + ambari-web/app/views/main/service/item.js | 120 +++++++------ ambari-web/test/views/main/service/item_test.js | 16 +- 4 files changed, 184 insertions(+), 132 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/8b7aa920/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 2c1d4cc..59559eb 100644 --- a/ambari-web/app/controllers/main/service/item.js +++ b/ambari-web/app/controllers/main/service/item.js @@ -45,6 +45,20 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow }, /** + * Map of service names and lists of sites they need to load + */ + serviceConfigsMap: { + 'OOZIE': ['oozie-env'] + }, + + /** + * Configs loaded to use for service actions menu + * + * format: {config-type: {property-name1: property-value1, property-name2: property-value2, ...}} + */ + configs: {}, + + /** * @type {boolean} * @default true */ @@ -56,42 +70,11 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow */ isServicesInfoLoaded: false, - initHosts: function() { - if (App.get('components.masters').length !== 0) { - ['HBASE_MASTER', 'HIVE_METASTORE', 'ZOOKEEPER_SERVER', 'FLUME_HANDLER', 'HIVE_SERVER', 'RANGER_KMS_SERVER', 'NIMBUS'].forEach(function(componentName) { - this.loadHostsWithoutComponent(componentName); - }, this); - } - }.observes('App.components.masters', 'content.hostComponents.length'), - - loadHostsWithoutComponent: function (componentName) { - var self = this; - var hostsWithComponent = App.HostComponent.find().filterProperty('componentName', componentName).mapProperty('hostName'); - - var hostsWithoutComponent = App.get('allHostNames').filter(function(hostName) { - return !hostsWithComponent.contains(hostName); - }); - - self.set('add' + componentName, function() { - App.get('router.mainAdminKerberosController').getKDCSessionState(function() { - self.addComponent(componentName); - }); - }); - - Em.defineProperty(self, 'addDisabledTooltip-' + componentName, Em.computed('isAddDisabled-' + componentName, 'addDisabledMsg-' + componentName, function() { - if (self.get('isAddDisabled-' + componentName)) { - return self.get('addDisabledMsg-' + componentName); - } - })); - - Em.defineProperty(self, 'isAddDisabled-' + componentName, Em.computed('hostsWithoutComponent-' + componentName, function() { - return self.get('hostsWithoutComponent-' + componentName).length === 0 ? 'disabled' : ''; - })); - - var disabledMsg = Em.I18n.t('services.summary.allHostsAlreadyRunComponent').format(componentName); - self.set('hostsWithoutComponent-' + componentName, hostsWithoutComponent); - self.set('addDisabledMsg-' + componentName, disabledMsg); - }, + /** + * Define whether configs for service actions menu were loaded + * @type {Boolean} + */ + isServiceConfigsLoaded: false, /** * flag to control router switch between service summary and configs @@ -123,6 +106,48 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow }.property('content.serviceName'), /** + * Load all config tags for loading configs + */ + loadConfigs: function(){ + if (this.get('serviceConfigsMap')[this.get('content.serviceName')]) { + this.set('isServiceConfigsLoaded', false); + App.ajax.send({ + name: 'config.tags', + sender: this, + success: 'onLoadConfigsTags', + error: 'onTaskError' + }); + } else { + this.set('isServiceConfigsLoaded', true); + } + }, + + /** + * Load all configs for sites from <code>serviceConfigsMap</code> for current service + * @param data + */ + onLoadConfigsTags: function (data) { + var self = this; + var sitesToLoad = this.get('serviceConfigsMap')[this.get('content.serviceName')]; + var loadedSites = data.Clusters.desired_configs; + var siteTagsToLoad = []; + for (var site in loadedSites) { + if (sitesToLoad.contains(site)) { + siteTagsToLoad.push({ + siteName: site, + tagName: loadedSites[site].tag + }); + } + } + App.router.get('configurationController').getConfigsByTags(siteTagsToLoad).done(function (configs) { + configs.forEach(function (site) { + self.get('configs')[site.type] = site.properties; + }); + self.set('isServiceConfigsLoaded', true); + }); + }, + + /** * Common method for ajax (start/stop service) responses * @param data * @param ajaxOptions @@ -779,60 +804,59 @@ App.MainServiceItemController = Em.Controller.extend(App.SupportClientConfigsDow var component = App.StackServiceComponent.find().findProperty('componentName', componentName); var componentDisplayName = component.get('displayName'); - self.loadHostsWithoutComponent(componentName); + App.get('router.mainAdminKerberosController').getKDCSessionState(function () { + return App.ModalPopup.show({ + primary: Em.computed.ifThenElse('anyHostsWithoutComponent', Em.I18n.t('hosts.host.addComponent.popup.confirm'), undefined), - 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'), - header: Em.I18n.t('popup.confirmation.commonHeader'), + addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(componentDisplayName), - addComponentMsg: Em.I18n.t('hosts.host.addComponent.msg').format(componentDisplayName), + selectHostMsg: Em.computed.i18nFormat('services.summary.selectHostForComponent', 'componentDisplayName'), - selectHostMsg: Em.computed.i18nFormat('services.summary.selectHostForComponent', 'componentDisplayName'), + thereIsNoHostsMsg: Em.computed.i18nFormat('services.summary.allHostsAlreadyRunComponent', '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'); - hostsWithoutComponent: function() { - return self.get("hostsWithoutComponent-" + this.get('componentName')); - }.property('componentName', 'self.hostsWithoutComponent-' + this.get('componentName')), + hostsWithComponent.forEach(function (host) { + result = result.without(host); + }); - anyHostsWithoutComponent: Em.computed.gt('hostsWithoutComponent.length', 0), + return result; + }.property(), - selectedHost: null, + anyHostsWithoutComponent: Em.computed.gt('hostsWithoutComponent.length', 0), - componentName: componentName, + selectedHost: null, - componentDisplayName: componentDisplayName, + componentName: componentName, - bodyClass: Em.View.extend({ - templateName: require('templates/main/service/add_host_popup') - }), + componentDisplayName: componentDisplayName, - 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); - } + bodyClass: Em.View.extend({ + templateName: require('templates/main/service/add_host_popup') + }), - // Remove host from 'without' collection to immediate recalculate add menu item state - var hostsWithoutComponent = this.get('hostsWithoutComponent'); - var index = hostsWithoutComponent.indexOf(this.get('selectedHost')); - if (index > -1) { - hostsWithoutComponent.splice(index, 1); - } + onPrimary: function () { + var selectedHost = this.get('selectedHost'); - self.set('hostsWithoutComponent-' + this.get('componentName'), hostsWithoutComponent); - this.hide(); - } + // 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(); + } + }); }); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/8b7aa920/ambari-web/app/mixins/common/configs/configs_saver.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mixins/common/configs/configs_saver.js b/ambari-web/app/mixins/common/configs/configs_saver.js index 383e4d0..d2b2623 100644 --- a/ambari-web/app/mixins/common/configs/configs_saver.js +++ b/ambari-web/app/mixins/common/configs/configs_saver.js @@ -619,6 +619,10 @@ App.ConfigsSaverMixin = Em.Mixin.create({ App.QuickViewLinks.proto().set('content', currentService); App.QuickViewLinks.proto().loadTags(); } + + // update configs for service actions + App.router.get('mainServiceItemController').loadConfigs(); + this.showSaveConfigsPopup(header, flag, message, messageClass, value, status, urlParams); this.clearAllRecommendations(); }, http://git-wip-us.apache.org/repos/asf/ambari/blob/8b7aa920/ambari-web/app/views/main/service/item.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/service/item.js b/ambari-web/app/views/main/service/item.js index cb9782c..659a0a5 100644 --- a/ambari-web/app/views/main/service/item.js +++ b/ambari-web/app/views/main/service/item.js @@ -41,52 +41,58 @@ App.MainServiceItemView = Em.View.extend({ addActionMap: function() { return [ - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.hbase.masterServer')), - service: 'HBASE', - component: 'HBASE_MASTER' - }, - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.hive.metastore')), - service: 'HIVE', - component: 'HIVE_METASTORE', - isHidden: !App.get('isHadoop22Stack') - }, - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.hive.server2')), - service: 'HIVE', - component: 'HIVE_SERVER', - isHidden: !App.get('isHadoop22Stack') - }, - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.zookeeper.server')), - service: 'ZOOKEEPER', - component: 'ZOOKEEPER_SERVER' - }, - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.flume.agentLabel')), - service: 'FLUME', - component: 'FLUME_HANDLER' - }, - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), App.format.role('RANGER_KMS_SERVER')), - service: 'RANGER_KMS', - component: 'RANGER_KMS_SERVER' - }, - { - cssClass: 'icon-plus', - 'label': '{0} {1}'.format(Em.I18n.t('add'), App.format.role('NIMBUS')), - service: 'STORM', - component: 'NIMBUS' - } - ] - }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.hbase.masterServer')), + service: 'HBASE', + component: 'HBASE_MASTER' + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.hive.metastore')), + service: 'HIVE', + component: 'HIVE_METASTORE', + isHidden: !App.get('isHadoop22Stack') + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.hive.server2')), + service: 'HIVE', + component: 'HIVE_SERVER', + isHidden: !App.get('isHadoop22Stack') + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.zookeeper.server')), + service: 'ZOOKEEPER', + component: 'ZOOKEEPER_SERVER' + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), Em.I18n.t('dashboard.services.flume.agentLabel')), + service: 'FLUME', + component: 'FLUME_HANDLER' + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), App.format.role('RANGER_KMS_SERVER')), + service: 'RANGER_KMS', + component: 'RANGER_KMS_SERVER' + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), App.format.role('NIMBUS')), + service: 'STORM', + component: 'NIMBUS' + }, + { + cssClass: 'icon-plus', + 'label': '{0} {1}'.format(Em.I18n.t('add'), App.format.role('OOZIE_SERVER')), + service: 'OOZIE', + component: 'OOZIE_SERVER' + } + ] + }, /** * Create option for MOVE_COMPONENT or ROLLING_RESTART task. * @@ -103,7 +109,7 @@ App.MainServiceItemView = Em.View.extend({ isMaintenanceSet: false, observeMaintenance: function() { - if (!this.get('isMaintenanceSet') && this.get('controller.isServicesInfoLoaded')) { + if (!this.get('isMaintenanceSet') && this.get('controller.isServicesInfoLoaded') && this.get('controller.isServiceConfigsLoaded')) { this.observeMaintenanceOnce(); } Em.run.once(this, 'clearIsMaintenanceSet'); @@ -200,15 +206,24 @@ App.MainServiceItemView = Em.View.extend({ component: hawqMasterComponent.get('componentName'), command: customCommandToStopCluster } - })) + })); } } self.addActionMap().filterProperty('service', serviceName).forEach(function(item) { if (App.get('components.addableToHost').contains(item.component)) { - item.action = 'add' + item.component; - item.disabled = self.get('controller.isAddDisabled-' + item.component); - item.tooltip = self.get('controller.addDisabledTooltip' + item.component); + + var isEnabled = App.HostComponent.find().filterProperty('componentName', item.component).length < App.get('allHostNames.length'); + + if (item.component === 'OOZIE_SERVER') { + isEnabled = isEnabled && !(Em.isEmpty(self.get('controller.configs.oozie-env.oozie_database')) || self.get('controller.configs.oozie-env.oozie_database') === 'New Derby Database'); + } + + item.action = 'addComponent'; + item.disabled = isEnabled ? '' : 'disabled'; + item.tooltip = isEnabled ? '' : Em.I18n.t('services.summary.allHostsAlreadyRunComponent').format(item.component); + item.context = item.component; + options.push(item); } }); @@ -282,10 +297,11 @@ App.MainServiceItemView = Em.View.extend({ this.get('controller').setStartStopState(); }, - maintenanceObsFields: ['isStopDisabled', 'isClientsOnlyService', 'content.isRestartRequired', 'isServicesInfoLoaded'], + maintenanceObsFields: ['isStopDisabled', 'isClientsOnlyService', 'content.isRestartRequired', 'isServicesInfoLoaded', 'isServiceConfigsLoaded'], willInsertElement: function () { var self = this; + this.get('controller').loadConfigs(); this.get('maintenanceObsFields').forEach(function (field) { self.addObserver('controller.' + field, self, 'observeMaintenance'); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/8b7aa920/ambari-web/test/views/main/service/item_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/views/main/service/item_test.js b/ambari-web/test/views/main/service/item_test.js index af94f01..9feb187 100644 --- a/ambari-web/test/views/main/service/item_test.js +++ b/ambari-web/test/views/main/service/item_test.js @@ -84,24 +84,28 @@ describe('App.MainServiceItemView', function () { { isMaintenanceSet: true, isServicesInfoLoaded: true, + isServiceConfigsLoaded: true, observeMaintenanceOnceCallCount: 0, title: 'actions array set, services info loaded' }, { isMaintenanceSet: true, isServicesInfoLoaded: false, + isServiceConfigsLoaded: true, observeMaintenanceOnceCallCount: 0, title: 'actions array set, services info not loaded' }, { isMaintenanceSet: false, isServicesInfoLoaded: true, + isServiceConfigsLoaded: true, observeMaintenanceOnceCallCount: 1, title: 'actions array not set, services info loaded' }, { isMaintenanceSet: false, isServicesInfoLoaded: false, + isServiceConfigsLoaded: true, observeMaintenanceOnceCallCount: 0, title: 'actions array not set, services info not loaded' } @@ -119,7 +123,8 @@ describe('App.MainServiceItemView', function () { it(item.title, function () { view.setProperties({ 'isMaintenanceSet': item.isMaintenanceSet, - 'controller.isServicesInfoLoaded': item.isServicesInfoLoaded + 'controller.isServicesInfoLoaded': item.isServicesInfoLoaded, + 'controller.isServiceConfigsLoaded': item.isServiceConfigsLoaded }); view.observeMaintenance(); expect(view.observeMaintenanceOnce.callCount).to.equal(item.observeMaintenanceOnceCallCount); @@ -206,7 +211,7 @@ describe('App.MainServiceItemView', function () { {"action": "restartAllHostComponents", "context": "ZOOKEEPER", "label": "Restart All", "cssClass": "icon-repeat", "disabled": false}, {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt", "disabled": false}, {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for ZooKeeper", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false}, - {"cssClass": "icon-plus", "label": "Add ZooKeeper Server", "service": "ZOOKEEPER", "component": "ZOOKEEPER_SERVER", "action": "addZOOKEEPER_SERVER", "disabled": "disabled", tooltip: ''}, + {"cssClass": "icon-plus", "label": "Add ZooKeeper Server", "service": "ZOOKEEPER", "component": "ZOOKEEPER_SERVER", "action": "addComponent", "disabled": "", tooltip: ''}, {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": false, "disabled": false, "hasSubmenu": false, "submenuOptions": []} ] }, @@ -319,7 +324,7 @@ describe('App.MainServiceItemView', function () { {"action": "rollingRestart", "label": "Restart Flumes", "cssClass": "icon-time", "disabled": false, "context": "FLUME_HANDLER"}, {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt", "disabled": false}, {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for Flume", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false}, - {"cssClass": "icon-plus", "label": "Add Flume Component", "service": "FLUME", "component": "FLUME_HANDLER", "action": "addFLUME_HANDLER", "disabled": '', tooltip: ''}, + {"cssClass": "icon-plus", "label": "Add Flume Component", "service": "FLUME", "component": "FLUME_HANDLER", "action": "addComponent", "disabled": '', tooltip: ''}, {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": true, "disabled": false, "hasSubmenu": false, "submenuOptions": []} ] }, @@ -355,7 +360,7 @@ describe('App.MainServiceItemView', function () { {"action": "rollingRestart", "label": "Restart RegionServers", "cssClass": "icon-time", "disabled": false, "context": "HBASE_REGIONSERVER"}, {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt", "disabled": false}, {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for HBase", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false}, - {"cssClass": "icon-plus", "label": "Add HBase Master", "service": "HBASE", "component": "HBASE_MASTER", "action": "addHBASE_MASTER", "disabled": '', tooltip: ''}, + {"cssClass": "icon-plus", "label": "Add HBase Master", "service": "HBASE", "component": "HBASE_MASTER", "action": "addComponent", "disabled": '', tooltip: ''}, {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": false, "disabled": false, "hasSubmenu": false, "submenuOptions": []} ] }, @@ -382,6 +387,7 @@ describe('App.MainServiceItemView', function () { {"action": "reassignMaster", "context": "OOZIE_SERVER", "label": "Move Oozie Server", "cssClass": "icon-share-alt", "disabled": false}, {"action": "runSmokeTest", "label": "Run Service Check", "cssClass": "icon-thumbs-up-alt", "disabled": false}, {"action": "turnOnOffPassive", "context": "Turn On Maintenance Mode for Oozie", "label": "Turn On Maintenance Mode", "cssClass": "icon-medkit", "disabled": false}, + {"cssClass": "icon-plus", "label": "Add Oozie Server", "service": "OOZIE", "component": "OOZIE_SERVER", "action": "addComponent", "disabled": "disabled", tooltip: Em.I18n.t('services.summary.allHostsAlreadyRunComponent').format('OOZIE_SERVER')}, {"action": "downloadClientConfigs", "label": "Download Client Configs", "cssClass": "icon-download-alt", "isHidden": false, "disabled": false, "hasSubmenu": false, "submenuOptions": []} ] }, @@ -449,6 +455,8 @@ describe('App.MainServiceItemView', function () { return ["HDFS", "MAPREDUCE2", "YARN", "HIVE", "HBASE", "PIG", "SQOOP", "OOZIE", "ZOOKEEPER", "FALCON", "STORM", "FLUME", "SLIDER", "KNOX", "KAFKA"]; case 'components.addableToHost': return ["DATANODE", "HDFS_CLIENT", "MAPREDUCE2_CLIENT", "NODEMANAGER", "YARN_CLIENT", "TEZ_CLIENT", "GANGLIA_MONITOR", "HCAT", "HIVE_CLIENT", "HIVE_METASTORE", "HIVE_SERVER", "WEBHCAT_SERVER", "HBASE_CLIENT", "HBASE_MASTER", "HBASE_REGIONSERVER", "PIG", "SQOOP", "OOZIE_CLIENT", "OOZIE_SERVER", "ZOOKEEPER_CLIENT", "ZOOKEEPER_SERVER", "FALCON_CLIENT", "SUPERVISOR", "FLUME_HANDLER", "METRICS_MONITOR", "KAFKA_BROKER", "KERBEROS_CLIENT", "KNOX_GATEWAY", "SLIDER", "SPARK_CLIENT"]; + case 'allHostNames.length': + return 2; default: return Em.get(App, k); }