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 2015/08/28 12:46:37 UTC

ambari git commit: AMBARI-12911. FE: Stack Meta for JDK support (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 6fc314414 -> 04d0eae4c


AMBARI-12911. FE: Stack Meta for JDK support (alexantonenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/04d0eae4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/04d0eae4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/04d0eae4

Branch: refs/heads/trunk
Commit: 04d0eae4cd789eb8e983e08a6f7bce7989df2b52
Parents: 6fc3144
Author: Alex Antonenko <hi...@gmail.com>
Authored: Fri Aug 28 13:14:47 2015 +0300
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Fri Aug 28 13:14:47 2015 +0300

----------------------------------------------------------------------
 .../controllers/global/cluster_controller.js    |  8 ++
 ambari-web/app/controllers/installer.js         | 53 ++++++++++-
 ambari-web/app/mappers/stack_mapper.js          |  4 +-
 ambari-web/app/messages.js                      |  4 +
 ambari-web/app/models/stack.js                  |  2 +
 ambari-web/app/routes/installer.js              | 14 +--
 ambari-web/app/utils/string_utils.js            |  6 +-
 ambari-web/test/controllers/installer_test.js   | 95 +++++++++++++++++++-
 8 files changed, 175 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/controllers/global/cluster_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js
index e182719..f564daa 100644
--- a/ambari-web/app/controllers/global/cluster_controller.js
+++ b/ambari-web/app/controllers/global/cluster_controller.js
@@ -41,6 +41,12 @@ App.ClusterController = Em.Controller.extend({
 
   isServiceMetricsLoaded: false,
 
+  /**
+   * Ambari uses custom jdk.
+   * @type {Boolean}
+   */
+  isCustomJDK: false,
+
   isHostContentLoaded: function () {
     return this.get('isHostsLoaded') && this.get('isComponentsStateLoaded');
   }.property('isHostsLoaded', 'isComponentsStateLoaded'),
@@ -349,6 +355,8 @@ App.ClusterController = Em.Controller.extend({
   loadAmbariPropertiesSuccess: function (data) {
     console.log('loading ambari properties');
     this.set('ambariProperties', data.RootServiceComponents.properties);
+    // Absence of 'jdk.name' and 'jce.name' properties says that ambari configured with custom jdk.
+    this.set('isCustomJDK', App.isEmptyObject(App.permit(data.RootServiceComponents.properties, ['jdk.name', 'jce.name'])));
   },
 
   loadAmbariPropertiesError: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/controllers/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/installer.js b/ambari-web/app/controllers/installer.js
index 3e97c4f..82e13f4 100644
--- a/ambari-web/app/controllers/installer.js
+++ b/ambari-web/app/controllers/installer.js
@@ -18,6 +18,7 @@
 
 
 var App = require('app');
+var stringUtils = require('utils/string_utils');
 
 App.InstallerController = App.WizardController.extend({
 
@@ -606,7 +607,15 @@ App.InstallerController = App.WizardController.extend({
       {
         type: 'async',
         callback: function () {
-          return this.loadStacks();
+          var dfd = $.Deferred();
+
+          this.loadStacks().always(function() {
+            App.router.get('clusterController').loadAmbariProperties().always(function() {
+              dfd.resolve();
+            });
+          });
+
+          return dfd.promise();
         }
       },
       {
@@ -719,5 +728,47 @@ App.InstallerController = App.WizardController.extend({
       var step = this.get('isStepDisabled').findProperty('step', i);
       step.set('value', true);
     }
+  },
+
+
+  /**
+   * Compare jdk versions used for ambari and selected stack.
+   * Validation check will fire only for non-custom jdk configuration.
+   *
+   * @param {Function} successCallback
+   * @param {Function} failCallback
+   */
+  validateJDKVersion: function (successCallback, failCallback) {
+    var selectedStack = App.Stack.find().findProperty('isSelected', true),
+        currentJDKVersion = App.router.get('clusterController.ambariProperties')['java.version'],
+        minJDKVersion = selectedStack.get('minJdkVersion'),
+        maxJDKVersion = selectedStack.get('maxJdkVersion'),
+        t = Em.I18n.t,
+        fCallback = failCallback || function() {},
+        sCallback = successCallback || function() {};
+
+    // Skip jdk check if min and max required version not set in stack definition.
+    if (!minJDKVersion && !maxJDKVersion) {
+      sCallback();
+      return;
+    }
+
+    if (currentJDKVersion) {
+      if (stringUtils.compareVersions(currentJDKVersion, selectedStack.get('minJdkVersion')) < 0 ||
+          stringUtils.compareVersions(selectedStack.get('maxJdkVersion'), currentJDKVersion) < 0) {
+        // checks and process only major part for now
+        var versionDistance = parseInt(maxJDKVersion.split('.')[1]) - parseInt(minJDKVersion.split('.')[1]);
+        var versionsList = [minJDKVersion];
+        for (var i = 1; i < (versionDistance + 1); i++) {
+          versionsList.push("" + minJDKVersion.split('.')[0] + '.' + (+minJDKVersion.split('.')[1] + i));
+        }
+        var versionsString = stringUtils.getFormattedStringFromArray(versionsList, t('or'));
+        var popupBody = t('popup.jdkValidation.body').format(selectedStack.get('stackName') + ' ' + selectedStack.get('stackVersion'), versionsString, currentJDKVersion);
+        App.showConfirmationPopup(sCallback, popupBody, fCallback, t('popup.jdkValidation.header'), t('common.proceedAnyway'), true);
+        return;
+      }
+    }
+    sCallback();
   }
+
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/mappers/stack_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/stack_mapper.js b/ambari-web/app/mappers/stack_mapper.js
index eb64ef6..75245e0 100644
--- a/ambari-web/app/mappers/stack_mapper.js
+++ b/ambari-web/app/mappers/stack_mapper.js
@@ -29,6 +29,8 @@ App.stackMapper = App.QuickDataMapper.create({
     active: 'active',
     parent_stack_version: 'parent_stack_version',
     min_upgrade_version: 'min_upgrade_version',
+    min_jdk_version: 'min_jdk',
+    max_jdk_version: 'max_jdk',
     is_selected: 'is_selected',
     config_types: 'config_types',
     operating_systems_key: 'operating_systems',
@@ -111,4 +113,4 @@ App.stackMapper = App.QuickDataMapper.create({
     App.store.loadMany(modelOS, resultOS);
     App.store.loadMany(modelStack, resultStack);
   }
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index e407623..ddaf2d8 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -63,6 +63,7 @@ Em.I18n.translations = {
   'add': 'Add',
   'op': 'op',
   'ops': 'ops',
+  'or': 'or',
 
 
   'common.access':'Access',
@@ -382,6 +383,9 @@ Em.I18n.translations = {
 
   'popup.dependent.configs.dependencies.for.groups': 'You are changing not default group, please select config group to which you want to save dependent configs from other services',
 
+  'popup.jdkValidation.header': 'Unsupported JDK',
+  'popup.jdkValidation.body': 'The {0} Stack requires JDK {1} but Ambari is configured for JDK {2}. This could result in error or problems with running your cluster.',
+
   'login.header':'Sign in',
   'login.username':'Username',
   'login.loginButton':'Sign in',

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/models/stack.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/stack.js b/ambari-web/app/models/stack.js
index e6cd0d8..0b1c9d2 100644
--- a/ambari-web/app/models/stack.js
+++ b/ambari-web/app/models/stack.js
@@ -25,6 +25,8 @@ App.Stack = DS.Model.extend({
   active: DS.attr('boolean'),  // All of the instances should have this value to true. We should map only those stacks that has active flag set to true
   parentStackVersion: DS.attr('string'),
   minUpgradeVersion: DS.attr('string'),
+  minJdkVersion: DS.attr('string'),
+  maxJdkVersion: DS.attr('string'),
   configTypes: DS.attr('object'),
   operatingSystems: DS.hasMany('App.OperatingSystem'),
   isSelected: DS.attr('boolean', {defaultValue: false}),

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/routes/installer.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/installer.js b/ambari-web/app/routes/installer.js
index dcd9925..70ec5e4 100644
--- a/ambari-web/app/routes/installer.js
+++ b/ambari-web/app/routes/installer.js
@@ -128,12 +128,14 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
     next: function (router) {
       var wizardStep1Controller = router.get('wizardStep1Controller');
       var installerController = router.get('installerController');
-      installerController.checkRepoURL(wizardStep1Controller).done(function () {
-        installerController.setDBProperty('service', undefined);
-        installerController.setStacks();
-        installerController.clearInstallOptions();
-        router.transitionTo('step2');
-      });
+      installerController.validateJDKVersion(function() {
+        installerController.checkRepoURL(wizardStep1Controller).done(function () {
+          installerController.setDBProperty('service', undefined);
+          installerController.setStacks();
+          installerController.clearInstallOptions();
+          router.transitionTo('step2');
+        });
+      }, function() {});
     }
   }),
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/app/utils/string_utils.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/string_utils.js b/ambari-web/app/utils/string_utils.js
index 48f8e52..3b14bfc 100644
--- a/ambari-web/app/utils/string_utils.js
+++ b/ambari-web/app/utils/string_utils.js
@@ -167,10 +167,12 @@ module.exports = {
    * var arr = [ambari, bigdata, hadoop]
    * getFormattedStringFromArray(arr);  // ambari, bigdata and hadoop
    * @param array {Array}  Array of elements
+   * @param [endSeparator=Em.I18n.t('and')] {String}
    * @returns {String}
    */
-  getFormattedStringFromArray: function (array) {
+  getFormattedStringFromArray: function (array, endSeparator) {
     var label = '';
+    endSeparator = endSeparator || Em.I18n.t('and');
     array.forEach(function (_arrElement) {
       if (array.length === 1) {
         label = _arrElement;
@@ -183,7 +185,7 @@ module.exports = {
           }
         }
         else {
-          label = label + ' ' + Em.I18n.t('and') + ' ' + _arrElement;
+          label = label + ' ' + endSeparator + ' ' + _arrElement;
         }
       }
     }, this);

http://git-wip-us.apache.org/repos/asf/ambari/blob/04d0eae4/ambari-web/test/controllers/installer_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/installer_test.js b/ambari-web/test/controllers/installer_test.js
index df5c8f4..23c00a7 100644
--- a/ambari-web/test/controllers/installer_test.js
+++ b/ambari-web/test/controllers/installer_test.js
@@ -469,7 +469,11 @@ describe('App.InstallerController', function () {
       var loadStacks = false;
       var checker = {
         loadStacks: function() {
-          loadStacks = true;
+          return {
+            always: function() {
+              loadStacks = true;
+            }
+          };
         }
       };
       installerController.loadMap['1'][0].callback.call(checker);
@@ -967,4 +971,93 @@ describe('App.InstallerController', function () {
 
   });
 
+  describe('#validateJDKVersion', function() {
+    var tests = [
+      {
+        isCustomJDK: false,
+        ambariProperties: {
+          'java.version': '1.8'
+        },
+        successCallbackCalled: false,
+        popupCalled: true,
+        stacks: [Em.Object.create({
+          minJdkVersion: '1.6',
+          maxJdkVersion: '1.7',
+          isSelected: true
+        })],
+        m: 'JDK 1.8, stack supports 1.6-1.7 popup should be displayed'
+      },
+      {
+        isCustomJDK: false,
+        ambariProperties: {
+          'java.version': '1.8'
+        },
+        successCallbackCalled: true,
+        popupCalled: false,
+        stacks: [Em.Object.create({
+          minJdkVersion: '1.6',
+          maxJdkVersion: '1.8',
+          isSelected: true
+        })],
+        m: 'JDK 1.8, stack supports 1.7-1.8 procceed installation without warning'
+      },
+      {
+        isCustomJDK: false,
+        ambariProperties: {
+          'java.version': '1.5'
+        },
+        successCallbackCalled: false,
+        popupCalled: true,
+        stacks: [Em.Object.create({
+          minJdkVersion: '1.6',
+          maxJdkVersion: '1.8',
+          isSelected: true
+        })],
+        m: 'JDK 1.5, stack supports 1.6-1.8, popup should be displayed'
+      },
+      {
+        isCustomJDK: false,
+        ambariProperties: {
+          'java.version': '1.8'
+        },
+        successCallbackCalled: true,
+        popupCalled: false,
+        stacks: [Em.Object.create({
+          isSelected: true
+        })],
+        m: 'JDK 1.8, min, max jdk missed in stack definition, procceed installation without warning'
+      },
+      {
+        isCustomJDK: true,
+        ambariProperties: {
+          'java.version': '1.8'
+        },
+        successCallbackCalled: true,
+        popupCalled: false,
+        stacks: [Em.Object.create({
+          minJdkVersion: '1.6',
+          maxJdkVersion: '1.8',
+          isSelected: true
+        })],
+        m: 'JDK 1.8, custom jdk location used, procceed installation without warning'
+      }
+    ];
+
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        sinon.stub(App.Stack, 'find').returns(test.stacks);
+        sinon.stub(App.router, 'get').withArgs('clusterController.isCustomJDK').returns(test.isCustomJDK)
+          .withArgs('clusterController.ambariProperties').returns(test.ambariProperties);
+        sinon.stub(App, 'showConfirmationPopup', Em.K);
+        var successCallback = sinon.spy();
+        installerController.validateJDKVersion(successCallback);
+        expect(successCallback.called).to.be.eql(test.successCallbackCalled);
+        expect(App.showConfirmationPopup.called).to.be.eql(test.popupCalled);
+        App.router.get.restore();
+        App.Stack.find.restore();
+        App.showConfirmationPopup.restore();
+      });
+    });
+  });
+
 });