You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by al...@apache.org on 2014/02/13 13:05:16 UTC
git commit: AMBARI-4647. YARN ATS: ATS component disappear on Install
Wizard (Buzhor Denys via alexantonenko)
Updated Branches:
refs/heads/trunk abbd10209 -> e11d100e5
AMBARI-4647. YARN ATS: ATS component disappear on Install Wizard (Buzhor Denys via alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e11d100e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e11d100e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e11d100e
Branch: refs/heads/trunk
Commit: e11d100e5bd9512570d09e19dd4a1c024c2e9da5
Parents: abbd102
Author: Alex Antonenko <hi...@gmail.com>
Authored: Thu Feb 13 14:03:09 2014 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Thu Feb 13 14:03:29 2014 +0200
----------------------------------------------------------------------
ambari-web/app/app.js | 159 +++++++++++++++++++++++++++------------
ambari-web/test/app_test.js | 133 +++++++++++++++++++++++++++++---
2 files changed, 233 insertions(+), 59 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e11d100e/ambari-web/app/app.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/app.js b/ambari-web/app/app.js
index c42e70b..4c1189a 100644
--- a/ambari-web/app/app.js
+++ b/ambari-web/app/app.js
@@ -74,69 +74,130 @@ module.exports = Em.Application.create({
}.property('router.clusterController.isLoaded'),
/**
- * List of exlcuded components for the current stack.
- * Setup available versions by 'stackVersions' property.
- *
- * For example:
- * {
- * service_name: 'YARN',
- * component_name: 'APP_TIMELINE_SERVER',
- * display_name: 'App Timeline Server',
- * isMaster: true,
- * isClient: false,
- * stackVersions: ['2.1.1'], - this component available only for HDP-2.1.1 stack
- * description: ''
- * }
+ * List of disabled components for the current stack with related info.
+ * Each element has followed structure:
+ * @type {Em.Object}
+ * @property componentName {String} - name of the component
+ * @property properties {Object} - mapped properties by site files,
+ * for example:
+ * properties: { global_properties: [], site_properties: [], etc. }
+ * @property reviewConfigs {Ember.Object} - reference review_configs.js
+ * @property serviceComponent {Object} - reference service_components.js
*
* @type {Array}
*/
stackDependedComponents: [],
+
+ /**
+ * Restore component data that was excluded from stack.
+ *
+ * @param component {Ember.Object} - #stackDependedComponents item
+ */
+ enableComponent: function(component) {
+ var propertyFileNames = ['global_properties', 'site_properties'];
+ var requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
+ // add component to service_components list
+ require('data/service_components').push(component.get('serviceComponent'));
+ // add properties
+ propertyFileNames.forEach(function(fileName) {
+ require(requirePrefix + fileName).configProperties = require(requirePrefix + fileName).configProperties.concat(component.get('properties.'+fileName));
+ });
+ var reviewConfigsService = require('data/review_configs')
+ .findProperty('config_name', 'services').config_value
+ .findProperty('service_name', component.get('serviceComponent.service_name'));
+ reviewConfigsService.get('service_components').pushObject(component.get('reviewConfigs'));
+ },
+ /**
+ * Disabling component. Remove related data from lists such as
+ * properties, review configs, service components.
+ *
+ * @param component {Object} - component info reference service_components.js
+ *
+ * @return {Ember.Object} - item of <code>stackDependedComponents</code> property
+ */
+ disableComponent: function(component) {
+ var componentCopy, propertyFileNames;
+ propertyFileNames = ['global_properties', 'site_properties'];
+ componentCopy = Em.Object.create({
+ componentName: component.component_name,
+ properties: {},
+ reviewConfigs: {},
+ configCategory: {},
+ serviceComponent: {}
+ });
+ componentCopy.set('serviceComponent', require('data/service_components').findProperty('component_name', component.component_name));
+ // remove component from service_components list
+ require('data/service_components').removeObject(componentCopy.get('serviceComponent'));
+ var serviceConfigsCategoryName, requirePrefix, serviceConfig;
+ // get service category name related to component
+ serviceConfig = require('data/service_configs').findProperty('serviceName', component.service_name);
+ serviceConfig.configCategories = serviceConfig.configCategories.filter(function(configCategory) {
+ if (configCategory.get('hostComponentNames')) {
+ serviceConfigsCategoryName = configCategory.get('name');
+ if (configCategory.get('hostComponentNames').contains(component.component_name)) {
+ componentCopy.set('configCategory', configCategory);
+ }
+ }
+ return true;
+ });
+ requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
+ var propertyObj = {};
+ propertyFileNames.forEach(function(propertyFileName) {
+ propertyObj[propertyFileName] = [];
+ });
+ // remove config properties related to this component
+ propertyFileNames.forEach(function(propertyFileName) {
+ var properties = require(requirePrefix + propertyFileName);
+ properties.configProperties = properties.configProperties.filter(function(property) {
+ if (property.category == serviceConfigsCategoryName) {
+ propertyObj[propertyFileName].push(property);
+ return false;
+ } else {
+ return true;
+ }
+ });
+ });
+ componentCopy.set('properties', propertyObj);
+ // remove component from review configs
+ var reviewConfigsService = require('data/review_configs')
+ .findProperty('config_name', 'services').config_value
+ .findProperty('service_name', component.service_name);
+ reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) {
+ if (serviceComponent.get('component_name') != component.component_name) {
+ return true;
+ } else {
+ componentCopy.set('reviewConfigs', serviceComponent);
+ return false;
+ }
+ }));
+ return componentCopy;
+ },
/**
- * Resolve dependency in components. Check forbidden components and
- * remove related data.
+ * Resolve dependency in components. Check forbidden/allowed components and
+ * remove/restore related data.
*/
handleStackDependedComponents: function() {
+ // need for unit testing
+ if (this.get('handleStackDependencyTest')) return;
var stackVersion, stackDependedComponents;
stackVersion = this.get('currentStackVersionNumber');
stackDependedComponents = [];
+ // disable components
require('data/service_components').filterProperty('stackVersions').forEach(function(component) {
if (!component.stackVersions.contains(stackVersion))
- stackDependedComponents.push(component);
- });
- if (stackDependedComponents.length > 0) {
- // start clean info about each component
- stackDependedComponents.forEach(function(component) {
- // remove component from service_components list
- require('data/service_components').removeObject(require('data/service_components').findProperty('component_name', component.component_name));
- var serviceConfig = require('data/service_configs').findProperty('serviceName', component.service_name);
- var serviceConfigsCategoryName, requirePrefix, propertyFileNames;
- propertyFileNames = ['global_properties', 'site_properties'];
- // remove config category assigned to this component
- serviceConfig.configCategories = serviceConfig.configCategories.filter(function(configCategory) {
- if (configCategory.get('hostComponentNames')) {
- serviceConfigsCategoryName = configCategory.get('name');
- return !configCategory.get('hostComponentNames').contains(component.component_name);
- }
- else
- return true;
- });
- requirePrefix = this.get('isHadoop2Stack') ? 'data/HDP2/' : 'data/';
- // remove config properties related to this component
- propertyFileNames.forEach(function(propertyFileName) {
- var properties = require(requirePrefix + propertyFileName);
- properties.configProperties = properties.configProperties.filter(function(property) {
- return property.category != serviceConfigsCategoryName;
- });
- });
- // remove component from review configs
- var reviewConfigsService = require('data/review_configs').findProperty('config_name', 'services').config_value.findProperty('service_name', component.service_name);
- reviewConfigsService.set('service_components', reviewConfigsService.get('service_components').filter(function (serviceComponent) {
- return serviceComponent.get('component_name') != component.component_name;
- }));
+ stackDependedComponents.push(this.disableComponent(component));
+ }, this);
+ // enable components
+ if (this.get('stackDependedComponents').length > 0) {
+ this.get('stackDependedComponents').forEach(function(component) {
+ if (component.get('serviceComponent').stackVersions.contains(this.get('currentStackVersionNumber'))) {
+ this.enableComponent(component);
+ stackDependedComponents = this.get('stackDependedComponents').removeObject(component);
+ }
}, this);
}
- this.set('stackDependedComponents', stackDependedComponents);
- }.observes('currentStackVersion'),
+ this.set('stackDependedComponents', this.get('stackDependedComponents').concat(stackDependedComponents));
+ }.observes('currentStackVersionNumber'),
/**
* List of components with allowed action for them
http://git-wip-us.apache.org/repos/asf/ambari/blob/e11d100e/ambari-web/test/app_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/app_test.js b/ambari-web/test/app_test.js
index cc3155c..f9f4087 100644
--- a/ambari-web/test/app_test.js
+++ b/ambari-web/test/app_test.js
@@ -18,21 +18,134 @@
var App = require('app');
-describe('#App.components', function() {
+describe('#App', function() {
- it('slaves and masters should not intersect', function() {
- var intersected = App.get('components.slaves').filter(function(item){
- return App.get('components.masters').contains(item);
+ describe('App.components', function() {
+
+ it('slaves and masters should not intersect', function() {
+ var intersected = App.get('components.slaves').filter(function(item){
+ return App.get('components.masters').contains(item);
+ });
+ expect(intersected).to.eql([]);
+ });
+
+ it('decommissionAllowed', function() {
+ expect(App.get('components.decommissionAllowed')).to.eql(["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER"]);
+ });
+
+ it('addableToHost', function() {
+ expect(App.get('components.addableToHost')).to.eql(["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "HBASE_MASTER", "ZOOKEEPER_SERVER", "SUPERVISOR"]);
});
- expect(intersected).to.eql([]);
- });
- it('decommissionAllowed', function() {
- expect(App.get('components.decommissionAllowed')).to.eql(["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER"]);
});
- it('addableToHost', function() {
- expect(App.get('components.addableToHost')).to.eql(["DATANODE", "TASKTRACKER", "NODEMANAGER", "HBASE_REGIONSERVER", "HBASE_MASTER", "ZOOKEEPER_SERVER", "SUPERVISOR"]);
+ describe('Disable/enable components', function() {
+ var testableComponent = {
+ service_name: 'YARN',
+ component_name: 'APP_TIMELINE_SERVER'
+ };
+ var expectedInfo = {
+ componentName: 'APP_TIMELINE_SERVER',
+ properties: {
+ global_properties: ['ats_host', 'apptimelineserver_heapsize'],
+ site_properties: ['yarn.ahs.fs-history-store.uri', 'yarn.ats.store.class', 'yarn.ats.leveldb-timeline-store.path']
+ },
+ reviewConfigs: {
+ component_name: 'APP_TIMELINE_SERVER'
+ },
+ configCategory: {
+ name: 'AppTimelineServer'
+ }
+ };
+ var globalProperties = require('data/HDP2/global_properties');
+ var siteProperties = require('data/HDP2/site_properties');
+ var serviceComponents = require('data/service_components');
+ var reviewConfigs = require('data/review_configs');
+ var disableResult;
+
+ App.set('currentStackVersion', 'HDP-2.1.1');
+ App.set('handleStackDependencyTest', true);
+
+ describe('#disableComponent()', function() {
+ disableResult = App.disableComponent(testableComponent);
+ // copy
+ var _globalProperties = $.extend({}, globalProperties);
+ var _siteProperties = $.extend({}, siteProperties);
+ var _serviceComponents = $.extend({}, serviceComponents);
+ var _reviewConfigs = JSON.parse(JSON.stringify(reviewConfigs));
+
+ describe('result validation', function() {
+
+ it('component name should be "' + expectedInfo.componentName + '"', function() {
+ expect(disableResult.get('componentName')).to.eql(expectedInfo.componentName);
+ });
+
+ it('config category name should be "' + expectedInfo.configCategory.name +'"', function() {
+ expect(disableResult.get('configCategory.name')).to.eql(expectedInfo.configCategory.name);
+ });
+
+ for(var siteName in expectedInfo.properties) {
+ (function(site) {
+ expectedInfo.properties[site].forEach(function(property) {
+ it(property + ' present in ' + site, function() {
+ expect(disableResult.get('properties.' + site).mapProperty('name')).to.include(property);
+ });
+ }, this);
+ })(siteName);
+ }
+
+ it('site and global properties should not be equal', function() {
+ expect(disableResult.get('properties.global_properties')).to.not.include.members(disableResult.get('properties.site_properties'));
+ });
+
+
+ });
+
+ describe('effect validation',function() {
+
+ it('should remove component from service_components object', function() {
+ expect(_serviceComponents.findProperty('component_name', testableComponent.component_name)).to.be.undefined;
+ });
+
+ it('should remove global properties of component', function() {
+ expect(_globalProperties.configProperties.mapProperty('name')).to.not.include.members(expectedInfo.properties.global_properties);
+ });
+
+ it('should remove site properties of component', function() {
+ expect(_siteProperties.configProperties.mapProperty('name')).to.not.include.members(expectedInfo.properties.site_properties);
+ });
+
+ it('should remove review config for component', function() {
+ var reviewConfig = _reviewConfigs.findProperty('config_name', 'services')
+ .config_value.findProperty('service_name', testableComponent.service_name)
+ .service_components.mapProperty('component_name');
+ expect(reviewConfig).to.not.include(expectedInfo.reviewConfigs.component_name);
+ });
+ });
+ });
+
+ describe('#enableComponent', function() {
+ App.enableComponent(disableResult);
+
+ it('should add component to service_components object', function() {
+ expect(serviceComponents.findProperty('component_name', testableComponent.component_name)).to.exist;
+ });
+
+ it('should add global properties of component', function() {
+ expect(globalProperties.configProperties.mapProperty('name')).to.include.members(expectedInfo.properties.global_properties);
+ });
+
+ it('should add site properties of component', function() {
+ expect(siteProperties.configProperties.mapProperty('name')).to.include.members(expectedInfo.properties.site_properties);
+ });
+
+ it('should add review config for component', function() {
+ var reviewConfig = reviewConfigs.findProperty('config_name', 'services')
+ .config_value.findProperty('service_name', testableComponent.service_name)
+ .get('service_components').mapProperty('component_name');
+ expect(reviewConfig).to.include(expectedInfo.reviewConfigs.component_name);
+ });
+ });
});
});