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);
+      });
+    });
   });
 
 });