Repository: ambari Updated Branches: refs/heads/trunk 101dc1d8f -> 9b8701c79
AMBARI-13812. Refactor RM HA step3 controller (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9b8701c7 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9b8701c7 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9b8701c7 Branch: refs/heads/trunk Commit: 9b8701c7934201e4593fced6128841031f7ef2b0 Parents: 101dc1d Author: Oleg Nechiporenko <onechipore...@apache.org> Authored: Tue Nov 10 16:15:57 2015 +0200 Committer: Oleg Nechiporenko <onechipore...@apache.org> Committed: Tue Nov 10 16:15:57 2015 +0200 ---------------------------------------------------------------------- .../resourceManager/step3_controller.js | 90 ++++----- .../configs/ha_config_initializer_class.js | 192 +++++++++++++++++++ .../utils/configs/nn_ha_config_initializer.js | 173 +---------------- .../utils/configs/rm_ha_config_initializer.js | 49 +++++ .../resourceManager/step3_controller_test.js | 70 +++++-- 5 files changed, 347 insertions(+), 227 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/9b8701c7/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js index 6296f02..5be5b03 100644 --- a/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js +++ b/ambari-web/app/controllers/main/admin/highAvailability/resourceManager/step3_controller.js @@ -16,7 +16,15 @@ * limitations under the License. */ +/** + * @typedef {object} rmHaConfigDependencies + * @property {string|number} webAddressPort + * @property {string|number} httpsWebAddressPort + * @property {string|number} zkClientPort + */ + var App = require('app'); +require('utils/configs/rm_ha_config_initializer'); App.RMHighAvailabilityWizardStep3Controller = Em.Controller.extend({ name: "rMHighAvailabilityWizardStep3Controller", @@ -87,20 +95,9 @@ App.RMHighAvailabilityWizardStep3Controller = Em.Controller.extend({ }, loadConfigsSuccessCallback: function (data, opt, params) { - var - zooCfg = data && data.items ? data.items.findProperty('type', 'zoo.cfg') : null, - yarnSite = data && data.items ? data.items.findProperty('type', 'yarn-site') : null, - portValue = zooCfg && Em.get(zooCfg, 'properties.clientPort'), - zkPort = portValue ? portValue : '2181', - webAddressPort = yarnSite && yarnSite.properties ? yarnSite.properties['yarn.resourcemanager.webapp.address'] : null, - httpsWebAddressPort = yarnSite && yarnSite.properties ? yarnSite. properties['yarn.resourcemanager.webapp.https.address'] : null; - - webAddressPort = webAddressPort && webAddressPort.match(/:[0-9]*/g) ? webAddressPort.match(/:[0-9]*/g)[0] : ":8088"; - httpsWebAddressPort = httpsWebAddressPort && httpsWebAddressPort.match(/:[0-9]*/g) ? httpsWebAddressPort.match(/:[0-9]*/g)[0] : ":8090"; - params = params.serviceConfig ? params.serviceConfig : arguments[4].serviceConfig; - this.setDynamicConfigValues(params, zkPort, webAddressPort, httpsWebAddressPort); + this.setDynamicConfigValues(params, data); this.setProperties({ selectedService: params, isLoaded: true @@ -108,40 +105,43 @@ App.RMHighAvailabilityWizardStep3Controller = Em.Controller.extend({ }, /** - * Set values dependent on host selection - * @param configs - * @param zkPort - * @param webAddressPort - * @param httpsWebAddressPort + * Get dependencies for new configs + * + * @param {{items: object[]}} data + * @returns {rmHaConfigDependencies} + * @private + * @method _prepareDependencies */ - setDynamicConfigValues: function (configs, zkPort, webAddressPort, httpsWebAddressPort) { - var - configProperties = configs.configs, - currentRMHost = this.get('content.rmHosts.currentRM'), - additionalRMHost = this.get('content.rmHosts.additionalRM'), - zooKeeperHostsWithPort = App.HostComponent.find().filterProperty('componentName', 'ZOOKEEPER_SERVER').map(function (item) { - return item.get('hostName') + ':' + zkPort; - }).join(','); - - configProperties.findProperty('name', 'yarn.resourcemanager.hostname.rm1').set('value', currentRMHost).set('recommendedValue', currentRMHost); - configProperties.findProperty('name', 'yarn.resourcemanager.hostname.rm2').set('value', additionalRMHost).set('recommendedValue', additionalRMHost); - configProperties.findProperty('name', 'yarn.resourcemanager.zk-address').set('value', zooKeeperHostsWithPort).set('recommendedValue', zooKeeperHostsWithPort); - - configProperties.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1') - .set('value', currentRMHost + webAddressPort) - .set('recommendedValue', currentRMHost + webAddressPort); - - configProperties.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2') - .set('value', additionalRMHost + webAddressPort) - .set('recommendedValue', additionalRMHost + webAddressPort); - - configProperties.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1') - .set('value', currentRMHost + httpsWebAddressPort) - .set('recommendedValue', currentRMHost + httpsWebAddressPort); - - configProperties.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2') - .set('value', additionalRMHost + httpsWebAddressPort) - .set('recommendedValue', additionalRMHost + httpsWebAddressPort); + _prepareDependencies: function (data) { + var ret = {}; + var zooCfg = data && data.items ? data.items.findProperty('type', 'zoo.cfg') : null; + var yarnSite = data && data.items ? data.items.findProperty('type', 'yarn-site') : null; + var portValue = zooCfg && Em.get(zooCfg, 'properties.clientPort'); + var webAddressPort = yarnSite && yarnSite.properties ? yarnSite.properties['yarn.resourcemanager.webapp.address'] : ''; + var httpsWebAddressPort = yarnSite && yarnSite.properties ? yarnSite. properties['yarn.resourcemanager.webapp.https.address'] : ''; + + ret.webAddressPort = webAddressPort && webAddressPort.contains(':') ? webAddressPort.split(':')[1] : '8088'; + ret.httpsWebAddressPort = httpsWebAddressPort && httpsWebAddressPort.contains(':') ? httpsWebAddressPort.split(':')[1] : '8090'; + ret.zkClientPort = portValue ? portValue : '2181'; + return ret; + }, + + /** + * Set values to the new configs + * + * @param {object} configs + * @param {object} data + * @returns {object} + * @method setDynamicConfigValues + */ + setDynamicConfigValues: function (configs, data) { + var topologyLocalDB = this.get('content').getProperties(['masterComponentHosts', 'slaveComponentHosts', 'hosts']); + var dependencies = this._prepareDependencies(data); + + configs.configs.forEach(function (config) { + App.RmHaConfigInitializer.initialValue(config, topologyLocalDB, dependencies); + }); + return configs; }, /** http://git-wip-us.apache.org/repos/asf/ambari/blob/9b8701c7/ambari-web/app/utils/configs/ha_config_initializer_class.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/ha_config_initializer_class.js b/ambari-web/app/utils/configs/ha_config_initializer_class.js new file mode 100644 index 0000000..0273d00 --- /dev/null +++ b/ambari-web/app/utils/configs/ha_config_initializer_class.js @@ -0,0 +1,192 @@ +/** + * 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. + */ + +var App = require('app'); +require('utils/configs/config_initializer_class'); + +/** + * @type {HaConfigInitializerClass} + */ +App.HaConfigInitializerClass = App.ConfigInitializerClass.extend({ + + /** + * Initializer for configs with value equal to the hostName where some component exists + * Value may be customized with prefix and suffix (see <code>initializer.modifier</code>) + * Port-value is calculated according to <code>initializer.portKey</code> or <code>initializer.port</code> values + * If calculated port-value is empty, it will be skipped (and ':' too) + * Value-examples: 'SOME_COOL_PREFIXhost1:port1SOME_COOL_SUFFIX', 'host1:port2' + * + * @param {object} configProperty + * @param {extendedTopologyLocalDB} localDB + * @param {nnHaConfigDependencies} dependencies + * @param {object} initializer + * @returns {object} + * @private + * @method _initAsHostWithPort + */ + _initAsHostWithPort: function (configProperty, localDB, dependencies, initializer) { + var hostName = localDB.masterComponentHosts.filterProperty('component', initializer.component).findProperty('isInstalled', initializer.componentExists).hostName; + var port = this.__getPort(dependencies, initializer); + var value = initializer.modifier.prefix + hostName + (port ? ':' + port : '') + initializer.modifier.suffix; + Em.setProperties(configProperty, { + value: value, + recommendedValue: value + }); + return configProperty; + }, + + /** + * Initializer for configs with value equal to the list of hosts where some component exists + * Value may be customized with prefix and suffix (see <code>initializer.modifier</code>) + * Delimiter between hostNames also may be customized in the <code>initializer.modifier</code> + * Port-value is calculated according to <code>initializer.portKey</code> or <code>initializer.port</code> values + * If calculated port-value is empty, it will be skipped (and ':' too) + * Value examples: 'SOME_COOL_PREFIXhost1:port,host2:port,host2:portSOME_COOL_SUFFIX', 'host1:port|||host2:port|||host2:port' + * + * @param {object} configProperty + * @param {topologyLocalDB} localDB + * @param {nnHaConfigDependencies} dependencies + * @param {object} initializer + * @returns {object} + * @private + * @method _initAsHostsWithPort + */ + _initAsHostsWithPort: function (configProperty, localDB, dependencies, initializer) { + var hostNames = localDB.masterComponentHosts.filterProperty('component', initializer.component).mapProperty('hostName'); + var port = this.__getPort(dependencies, initializer); + var value = initializer.modifier.prefix + hostNames.map(function (hostName) { + return hostName + (port ? ':' + port : ''); + }).join(initializer.modifier.delimiter) + initializer.modifier.suffix; + Em.setProperties(configProperty, { + value: value, + recommendedValue: value + }); + return configProperty; + }, + + /** + * Returns port-value from <code>dependencies</code> accorfing to <code>initializer.portKey</code> or <code>initializer.port</code> values + * + * @param {nnHaConfigDependencies} dependencies + * @param {object} initializer + * @returns {string|number} + * @private + * @method __getPort + */ + __getPort: function (dependencies, initializer) { + var portKey = initializer.portKey; + if (portKey) { + return dependencies[portKey]; + } + return initializer.port; + } + +}); + +App.HaConfigInitializerClass.reopenClass({ + + /** + * Settings for <code>host_with_port</code>-initializer + * Used for configs with value equal to hostName where some component exists concatenated with port-value + * Port-value is calculated according to <code>port</code> and <code>portFromDependencies</code> values + * If <code>portFromDependencies</code> is <code>true</code>, <code>port</code>-value is used as key of the <code>dependencies</code> (where real port-value is) + * Otherwise - <code>port</code>-value used as is + * If calculated port-value is empty, it will be skipped (and ':' too) + * Value also may be customized with prefix and suffix + * + * @param {string} component needed component + * @param {boolean} componentExists component already exists or just going to be installed + * @param {string} prefix='' + * @param {string} suffix='' + * @param {string} port + * @param {boolean} [portFromDependencies=false] + * @returns {{type: string, component: string, componentExists: boolean, modifier: {prefix: (string), suffix: (string)}}} + * @method getHostWithPortConfig + * @static + */ + getHostWithPortConfig: function (component, componentExists, prefix, suffix, port, portFromDependencies) { + if (arguments.length < 6) { + portFromDependencies = false; + } + prefix = prefix || ''; + suffix = suffix || ''; + var ret = { + type: 'host_with_port', + component: component, + componentExists: componentExists, + modifier: { + prefix: prefix, + suffix: suffix + } + }; + if (portFromDependencies) { + ret.portKey = port; + } + else { + ret.port = port; + } + return ret; + }, + + /** + * Settings for <code>hosts_with_port</code>-initializer + * Used for configs with value equal to the list of hostNames with port + * Value also may be customized with prefix, suffix and delimiter between host:port elements + * Port-value is calculated according to <code>port</code> and <code>portFromDependencies</code> values + * If <code>portFromDependencies</code> is <code>true</code>, <code>port</code>-value is used as key of the <code>dependencies</code> (where real port-value is) + * Otherwise - <code>port</code>-value used as is + * If calculated port-value is empty, it will be skipped (and ':' too) + * + * @param {string} component hosts where this component exists are used as config-value + * @param {string} prefix='' substring added before hosts-list + * @param {string} suffix='' substring added after hosts-list + * @param {string} delimiter=',' delimiter between hosts in the value + * @param {string} port if <code>portFromDependencies</code> is <code>false</code> this value is used as port for hosts + * if <code>portFromDependencies</code> is <code>true</code> `port` is used as key in the <code>dependencies</code> to get real port-value + * @param {boolean} portFromDependencies=false true - use <code>port</code> as key for <code>dependencies</code> to get real port-value, + * false - use <code>port</code> as port-value + * @returns {{type: string, component: string, modifier: {prefix: (string), suffix: (string), delimiter: (string)}}} + * @method getHostsWithPortConfig + * @static + */ + getHostsWithPortConfig: function (component, prefix, suffix, delimiter, port, portFromDependencies) { + if (arguments.length < 6) { + portFromDependencies = false; + } + prefix = prefix || ''; + suffix = suffix || ''; + delimiter = delimiter || ','; + var ret = { + type: 'hosts_with_port', + component: component, + modifier: { + prefix: prefix, + suffix: suffix, + delimiter: delimiter + } + }; + if (portFromDependencies) { + ret.portKey = port; + } + else { + ret.port = port; + } + return ret; + } + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/9b8701c7/ambari-web/app/utils/configs/nn_ha_config_initializer.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/nn_ha_config_initializer.js b/ambari-web/app/utils/configs/nn_ha_config_initializer.js index ef9e9c8..7b7e317 100644 --- a/ambari-web/app/utils/configs/nn_ha_config_initializer.js +++ b/ambari-web/app/utils/configs/nn_ha_config_initializer.js @@ -17,7 +17,7 @@ */ var App = require('app'); -require('utils/configs/config_initializer_class'); +require('utils/configs/ha_config_initializer_class'); /** * @typedef {topologyLocalDB} extendedTopologyLocalDB @@ -40,89 +40,6 @@ function getRenameWithNamespaceConfig(toReplace) { } /** - * Settings for <code>host_with_port</code>-initializer - * Used for configs with value equal to hostName where some component exists concatenated with port-value - * Port-value is calculated according to <code>port</code> and <code>portFromDependencies</code> values - * If <code>portFromDependencies</code> is <code>true</code>, <code>port</code>-value is used as key of the <code>dependencies</code> (where real port-value is) - * Otherwise - <code>port</code>-value used as is - * Value also may be customized with prefix and suffix - * - * @param {string} component needed component - * @param {boolean} componentExists component already exists or just going to be installed - * @param {string} prefix='' - * @param {string} suffix='' - * @param {string} port - * @param {boolean} portFromDependencies=false - * @returns {{type: string, component: string, componentExists: boolean, modifier: {prefix: (string), suffix: (string)}}} - */ -function getHostWithPortConfig(component, componentExists, prefix, suffix, port, portFromDependencies) { - if (arguments.length < 6) { - portFromDependencies = false; - } - prefix = prefix || ''; - suffix = suffix || ''; - var ret = { - type: 'host_with_port', - component: component, - componentExists: componentExists, - modifier: { - prefix: prefix, - suffix: suffix - } - }; - if (portFromDependencies) { - ret.portKey = port; - } - else { - ret.port = port; - } - return ret; -} - -/** - * Settings for <code>hosts_with_port</code>-initializer - * Used for configs with value equal to the list of hostNames with port - * Value also may be customized with prefix, suffix and delimiter between host:port elements - * Port-value is calculated according to <code>port</code> and <code>portFromDependencies</code> values - * If <code>portFromDependencies</code> is <code>true</code>, <code>port</code>-value is used as key of the <code>dependencies</code> (where real port-value is) - * Otherwise - <code>port</code>-value used as is - * - * @param {string} component hosts where this component exists are used as config-value - * @param {string} prefix='' substring added before hosts-list - * @param {string} suffix='' substring added after hosts-list - * @param {string} delimiter=',' delimiter between hosts in the value - * @param {string} port if <code>portFromDependencies</code> is <code>false</code> this value is used as port for hosts - * if <code>portFromDependencies</code> is <code>true</code> `port` is used as key in the <code>dependencies</code> to get real port-value - * @param {boolean} portFromDependencies=false true - use <code>port</code> as key for <code>dependencies</code> to get real port-value, - * false - use <code>port</code> as port-value - * @returns {{type: string, component: string, modifier: {prefix: (string), suffix: (string), delimiter: (string)}}} - */ -function getHostsWithPortConfig(component, prefix, suffix, delimiter, port, portFromDependencies) { - if (arguments.length < 6) { - portFromDependencies = false; - } - prefix = prefix || ''; - suffix = suffix || ''; - delimiter = delimiter || ','; - var ret = { - type: 'hosts_with_port', - component: component, - modifier: { - prefix: prefix, - suffix: suffix, - delimiter: delimiter - } - }; - if (portFromDependencies) { - ret.portKey = port; - } - else { - ret.port = port; - } - return ret; -} - -/** * Settings for <code>namespace</code>-initializer * Used for configs with value equal to the <code>namespaceId</code> (provided by user on the wizard's 1st step) * Value may be customized with prefix and suffix @@ -162,42 +79,42 @@ function getReplaceNamespaceConfig(toReplace) { * * @class {NnHaConfigInitializer} */ -App.NnHaConfigInitializer = App.ConfigInitializerClass.create({ +App.NnHaConfigInitializer = App.HaConfigInitializerClass.create({ initializers: { 'dfs.ha.namenodes.${dfs.nameservices}': getRenameWithNamespaceConfig('${dfs.nameservices}'), 'dfs.namenode.rpc-address.${dfs.nameservices}.nn1': [ - getHostWithPortConfig('NAMENODE', true, '', '', 'nnRpcPort', true), + App.HaConfigInitializerClass.getHostWithPortConfig('NAMENODE', true, '', '', 'nnRpcPort', true), getRenameWithNamespaceConfig('${dfs.nameservices}') ], 'dfs.namenode.rpc-address.${dfs.nameservices}.nn2': [ - getHostWithPortConfig('NAMENODE', false, '', '', '8020', false), + App.HaConfigInitializerClass.getHostWithPortConfig('NAMENODE', false, '', '', '8020', false), getRenameWithNamespaceConfig('${dfs.nameservices}') ], 'dfs.namenode.http-address.${dfs.nameservices}.nn1': [ - getHostWithPortConfig('NAMENODE', true, '', '', 'nnHttpPort', true), + App.HaConfigInitializerClass.getHostWithPortConfig('NAMENODE', true, '', '', 'nnHttpPort', true), getRenameWithNamespaceConfig('${dfs.nameservices}') ], 'dfs.namenode.http-address.${dfs.nameservices}.nn2': [ - getHostWithPortConfig('NAMENODE', false, '', '', '50070', false), + App.HaConfigInitializerClass.getHostWithPortConfig('NAMENODE', false, '', '', '50070', false), getRenameWithNamespaceConfig('${dfs.nameservices}') ], 'dfs.namenode.https-address.${dfs.nameservices}.nn1': [ - getHostWithPortConfig('NAMENODE', true, '', '', 'nnHttpsPort', true), + App.HaConfigInitializerClass.getHostWithPortConfig('NAMENODE', true, '', '', 'nnHttpsPort', true), getRenameWithNamespaceConfig('${dfs.nameservices}') ], 'dfs.namenode.https-address.${dfs.nameservices}.nn2': [ - getHostWithPortConfig('NAMENODE', false, '', '', '50470', false), + App.HaConfigInitializerClass.getHostWithPortConfig('NAMENODE', false, '', '', '50470', false), getRenameWithNamespaceConfig('${dfs.nameservices}') ], 'dfs.client.failover.proxy.provider.${dfs.nameservices}': getRenameWithNamespaceConfig('${dfs.nameservices}'), 'dfs.nameservices': getNamespaceConfig(), 'fs.defaultFS': getNamespaceConfig('hdfs://'), 'dfs.namenode.shared.edits.dir': [ - getHostsWithPortConfig('JOURNALNODE', 'qjournal://', '/${dfs.nameservices}', ';', '8485', false), + App.HaConfigInitializerClass.getHostsWithPortConfig('JOURNALNODE', 'qjournal://', '/${dfs.nameservices}', ';', '8485', false), getReplaceNamespaceConfig('${dfs.nameservices}') ], - 'ha.zookeeper.quorum': getHostsWithPortConfig('ZOOKEEPER_SERVER', '', '', ',', 'zkClientPort', true) + 'ha.zookeeper.quorum': App.HaConfigInitializerClass.getHostsWithPortConfig('ZOOKEEPER_SERVER', '', '', ',', 'zkClientPort', true) }, uniqueInitializers: { @@ -303,76 +220,6 @@ App.NnHaConfigInitializer = App.ConfigInitializerClass.create({ }, /** - * Initializer for configs with value equal to the hostName where some component exists - * Value may be customized with prefix and suffix (see <code>initializer.modifier</code>) - * Port-value is calculated according to <code>initializer.portKey</code> or <code>initializer.port</code> values - * Value-examples: 'SOME_COOL_PREFIXhost1:port1SOME_COOL_SUFFIX', 'host1:port2' - * - * @param {object} configProperty - * @param {extendedTopologyLocalDB} localDB - * @param {nnHaConfigDependencies} dependencies - * @param {object} initializer - * @returns {object} - * @private - * @method _initAsHostWithPort - */ - _initAsHostWithPort: function (configProperty, localDB, dependencies, initializer) { - var hostName = localDB.masterComponentHosts.filterProperty('component', initializer.component).findProperty('isInstalled', initializer.componentExists).hostName; - var port = this.__getPort(dependencies, initializer); - var value = initializer.modifier.prefix + hostName + ':' + port + initializer.modifier.suffix; - Em.setProperties(configProperty, { - value: value, - recommendedValue: value - }); - return configProperty; - }, - - /** - * Initializer for configs with value equal to the list of hosts where some component exists - * Value may be customized with prefix and suffix (see <code>initializer.modifier</code>) - * Delimiter between hostNames also may be customized in the <code>initializer.modifier</code> - * Port-value is calculated according to <code>initializer.portKey</code> or <code>initializer.port</code> values - * Value examples: 'SOME_COOL_PREFIXhost1:port,host2:port,host2:portSOME_COOL_SUFFIX', 'host1:port|||host2:port|||host2:port' - * - * @param {object} configProperty - * @param {topologyLocalDB} localDB - * @param {nnHaConfigDependencies} dependencies - * @param {object} initializer - * @returns {object} - * @private - * @method _initAsHostsWithPort - */ - _initAsHostsWithPort: function (configProperty, localDB, dependencies, initializer) { - var hostNames = localDB.masterComponentHosts.filterProperty('component', initializer.component).mapProperty('hostName'); - var port = this.__getPort(dependencies, initializer); - var value = initializer.modifier.prefix + hostNames.map(function (hostName) { - return hostName + ':' + port; - }).join(initializer.modifier.delimiter) + initializer.modifier.suffix; - Em.setProperties(configProperty, { - value: value, - recommendedValue: value - }); - return configProperty; - }, - - /** - * Returns port-value from <code>dependencies</code> accorfing to <code>initializer.portKey</code> or <code>initializer.port</code> values - * - * @param {nnHaConfigDependencies} dependencies - * @param {object} initializer - * @returns {string|number} - * @private - * @method __getPort - */ - __getPort: function (dependencies, initializer) { - var portKey = initializer.portKey; - if (portKey) { - return dependencies[portKey]; - } - return initializer.port; - }, - - /** * Unique initializer for <code>hbase.rootdir</code> * * @param {object} configProperty http://git-wip-us.apache.org/repos/asf/ambari/blob/9b8701c7/ambari-web/app/utils/configs/rm_ha_config_initializer.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/utils/configs/rm_ha_config_initializer.js b/ambari-web/app/utils/configs/rm_ha_config_initializer.js new file mode 100644 index 0000000..1b1885a --- /dev/null +++ b/ambari-web/app/utils/configs/rm_ha_config_initializer.js @@ -0,0 +1,49 @@ +/** + * 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. + */ + +var App = require('app'); +require('utils/configs/config_initializer_class'); + +/** + * + * @class {RmHaConfigInitializer} + */ +App.RmHaConfigInitializer = App.HaConfigInitializerClass.create({ + + initializers: { + 'yarn.resourcemanager.hostname.rm1': App.HaConfigInitializerClass.getHostWithPortConfig('RESOURCEMANAGER', true, '', '', ''), + 'yarn.resourcemanager.hostname.rm2': App.HaConfigInitializerClass.getHostWithPortConfig('RESOURCEMANAGER', false,'', '', ''), + 'yarn.resourcemanager.zk-address': App.HaConfigInitializerClass.getHostsWithPortConfig('ZOOKEEPER_SERVER', '', '', ',', 'zkClientPort', true), + 'yarn.resourcemanager.webapp.address.rm1': App.HaConfigInitializerClass.getHostWithPortConfig('RESOURCEMANAGER', true, '', '', 'webAddressPort', true), + 'yarn.resourcemanager.webapp.address.rm2': App.HaConfigInitializerClass.getHostWithPortConfig('RESOURCEMANAGER', false, '', '', 'webAddressPort', true), + 'yarn.resourcemanager.webapp.https.address.rm1': App.HaConfigInitializerClass.getHostWithPortConfig('RESOURCEMANAGER', true, '', '', 'httpsWebAddressPort', true), + 'yarn.resourcemanager.webapp.https.address.rm2': App.HaConfigInitializerClass.getHostWithPortConfig('RESOURCEMANAGER', false, '', '', 'httpsWebAddressPort', true) + }, + + uniqueInitializers: {}, + + initializerTypes: { + host_with_port: { + method: '_initAsHostWithPort' + }, + hosts_with_port: { + method: '_initAsHostsWithPort' + } + } + +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/9b8701c7/ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js ---------------------------------------------------------------------- diff --git a/ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js b/ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js index ae4dda0..b2e8f59 100644 --- a/ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js +++ b/ambari-web/test/controllers/main/admin/highAvailability/resourceManager/step3_controller_test.js @@ -23,7 +23,9 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { describe('#isSubmitDisabled', function () { - var controller = App.RMHighAvailabilityWizardStep3Controller.create(), + var controller = App.RMHighAvailabilityWizardStep3Controller.create({ + content: Em.Object.create({}) + }), cases = [ { isLoaded: false, @@ -48,7 +50,9 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { describe('#loadConfigTagsSuccessCallback', function () { - var controller = App.RMHighAvailabilityWizardStep3Controller.create(); + var controller = App.RMHighAvailabilityWizardStep3Controller.create({ + content: Em.Object.create({}) + }); beforeEach(function () { sinon.stub(App.ajax, 'send', Em.K); @@ -82,7 +86,9 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { describe('#loadConfigsSuccessCallback', function () { - var controller = App.RMHighAvailabilityWizardStep3Controller.create(), + var controller = App.RMHighAvailabilityWizardStep3Controller.create({ + content: Em.Object.create({}) + }), cases = [ { 'items': [], @@ -173,7 +179,6 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { controller.loadConfigsSuccessCallback({ items: item.items }, {}, item.params); - expect(controller.setDynamicConfigValues.args[0]).to.eql([{}, item.port, item.webAddressPort, item.httpsWebAddressPort]); expect(controller.get('selectedService')).to.eql({}); expect(controller.get('isLoaded')).to.be.true; }); @@ -183,7 +188,9 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { describe('#loadConfigsSuccessCallback=loadConfigsErrorCallback(we have one callback for bouth cases)', function () { - var controller = App.RMHighAvailabilityWizardStep3Controller.create(); + var controller = App.RMHighAvailabilityWizardStep3Controller.create({ + content: Em.Object.create({}) + }); beforeEach(function () { sinon.stub(controller, 'setDynamicConfigValues', Em.K); @@ -197,7 +204,6 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { controller.loadConfigsSuccessCallback({}, {}, {}, {}, { serviceConfig: {} }); - expect(controller.setDynamicConfigValues.args[0]).to.eql([{}, '2181', ':8088', ':8090']); expect(controller.get('selectedService')).to.eql({}); expect(controller.get('isLoaded')).to.be.true; }); @@ -206,13 +212,39 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { describe('#setDynamicConfigValues', function () { + var data = { + items: [ + { + type: 'zoo.cfg', + properties: { + clientPort: 2222 + } + }, + { + type: 'yarn-site', + properties: { + 'yarn.resourcemanager.webapp.address': 'lclhst:1234', + 'yarn.resourcemanager.webapp.https.address': 'lclhst:4321' + } + } + ] + }; + var controller = App.RMHighAvailabilityWizardStep3Controller.create({ - content: { + content: Em.Object.create({ + masterComponentHosts: [ + {component: 'RESOURCEMANAGER', hostName: 'h0', isInstalled: true}, + {component: 'RESOURCEMANAGER', hostName: 'h1', isInstalled: false}, + {component: 'ZOOKEEPER_SERVER', hostName: 'h2', isInstalled: true}, + {component: 'ZOOKEEPER_SERVER', hostName: 'h3', isInstalled: true} + ], + slaveComponentHosts: [], + hosts: {}, rmHosts: { currentRM: 'h0', additionalRM: 'h1' } - } + }) }), configs = { configs: [ @@ -264,24 +296,24 @@ describe('App.RMHighAvailabilityWizardStep3Controller', function () { }); it('setting new RM properties values', function () { - controller.setDynamicConfigValues(configs, '2181', ':8088', ':8090'); + controller.setDynamicConfigValues(configs, data); expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm1').get('value')).to.equal('h0'); expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm1').get('recommendedValue')).to.equal('h0'); expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm2').get('value')).to.equal('h1'); expect(configs.configs.findProperty('name', 'yarn.resourcemanager.hostname.rm2').get('recommendedValue')).to.equal('h1'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1').get('value')).to.equal('h0:8088'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1').get('recommendedValue')).to.equal('h0:8088'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2').get('value')).to.equal('h1:8088'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2').get('recommendedValue')).to.equal('h1:8088'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1').get('value')).to.equal('h0:1234'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm1').get('recommendedValue')).to.equal('h0:1234'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2').get('value')).to.equal('h1:1234'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.address.rm2').get('recommendedValue')).to.equal('h1:1234'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1').get('value')).to.equal('h0:8090'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1').get('recommendedValue')).to.equal('h0:8090'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2').get('value')).to.equal('h1:8090'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2').get('recommendedValue')).to.equal('h1:8090'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1').get('value')).to.equal('h0:4321'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm1').get('recommendedValue')).to.equal('h0:4321'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2').get('value')).to.equal('h1:4321'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.webapp.https.address.rm2').get('recommendedValue')).to.equal('h1:4321'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.zk-address').get('value')).to.equal('h2:2181,h3:2181'); - expect(configs.configs.findProperty('name', 'yarn.resourcemanager.zk-address').get('recommendedValue')).to.equal('h2:2181,h3:2181'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.zk-address').get('value')).to.equal('h2:2222,h3:2222'); + expect(configs.configs.findProperty('name', 'yarn.resourcemanager.zk-address').get('recommendedValue')).to.equal('h2:2222,h3:2222'); }); });