You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ak...@apache.org on 2015/04/21 18:11:39 UTC

ambari git commit: AMBARI-10632. Ranger Admin HA Wizard: Get Started step. (akovalenko)

Repository: ambari
Updated Branches:
  refs/heads/trunk 2dd2548f3 -> 2557d9a8f


AMBARI-10632. Ranger Admin HA Wizard: Get Started step. (akovalenko)


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

Branch: refs/heads/trunk
Commit: 2557d9a8fb7d9e2f7fe3b2e0deb5b5bec0d14dc1
Parents: 2dd2548
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Tue Apr 21 18:44:14 2015 +0300
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Tue Apr 21 19:11:19 2015 +0300

----------------------------------------------------------------------
 .../rangerAdmin/step1_controller.js             | 26 ++++++++++-
 .../rangerAdmin/wizard_controller.js            |  2 +
 ambari-web/app/controllers/wizard.js            | 30 +++++++++++--
 ambari-web/app/messages.js                      |  7 +++
 .../app/routes/ra_high_availability_routes.js   |  9 ++--
 .../highAvailability/rangerAdmin/step1.hbs      | 21 ++++++++-
 ambari-web/app/utils/validator.js               | 10 +++++
 ambari-web/test/controllers/wizard_test.js      | 45 ++++++++++++++++++++
 ambari-web/test/utils/validator_test.js         | 17 ++++++++
 9 files changed, 158 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step1_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step1_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step1_controller.js
index d431ec9..32e0dff 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step1_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/step1_controller.js
@@ -17,8 +17,32 @@
  */
 
 var App = require('app');
+var validator = require('utils/validator');
 
 App.RAHighAvailabilityWizardStep1Controller = Em.Controller.extend({
-  name: "rAHighAvailabilityWizardStep1Controller"
+  name: "rAHighAvailabilityWizardStep1Controller",
+
+  /**
+   * Define if typed load balancer URL is valid URL
+   * @type {Boolean}
+   */
+  isloadBalancerURLValid: function () {
+    return validator.isValidURL(this.get('content.loadBalancerURL'));
+  }.property('content.loadBalancerURL'),
+
+  /**
+   * Define if show load balancer URL error
+   * do not show is input-field is empty
+   * @type {Boolean}
+   */
+  showloadBalancerURLError: function () {
+    return this.get('content.loadBalancerURL') && !this.get('isloadBalancerURLValid');
+  }.property('isloadBalancerURLValid', 'content.loadBalancerURL'),
+
+  /**
+   * Define either Submit is disabled or enabled
+   * @type {Bolean}
+   */
+  isSubmitDisabled: Ember.computed.not('isloadBalancerURLValid')
 });
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js
index ebfb2ee..5638c87 100644
--- a/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js
+++ b/ambari-web/app/controllers/main/admin/highAvailability/rangerAdmin/wizard_controller.js
@@ -30,6 +30,7 @@ App.RAHighAvailabilityWizardController = App.WizardController.extend({
   content: Em.Object.create({
     controllerName: 'rAHighAvailabilityWizardController',
     cluster: null,
+    loadBalancerURL: null,
     hosts: null,
     services: null,
     masterComponentHosts: null
@@ -59,6 +60,7 @@ App.RAHighAvailabilityWizardController = App.WizardController.extend({
         type: 'sync',
         callback: function () {
           this.load('cluster');
+          this.load('loadBalancerURL');
         }
       }
     ],

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index d1148a9..5e30777 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -307,6 +307,30 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   },
 
   /**
+   * Convert any object or array to pure JS instance without inherit properties
+   * It is used to convert Ember.Object to pure JS Object and Ember.Array to pure JS Array
+   * @param originalInstance
+   * @returns {*}
+   */
+  toJSInstance: function (originalInstance) {
+    var convertedInstance = originalInstance;
+    if (Em.isArray(originalInstance)) {
+      convertedInstance = [];
+      originalInstance.forEach(function (element) {
+        convertedInstance.push(this.toJSInstance(element));
+      }, this)
+    } else if (originalInstance && typeof originalInstance === 'object') {
+      convertedInstance = {};
+      for (var property in originalInstance) {
+        if (originalInstance.hasOwnProperty(property)) {
+          convertedInstance[property] = this.toJSInstance(originalInstance[property]);
+        }
+      }
+    }
+    return convertedInstance
+  },
+
+  /**
    * save status of the cluster. This is called from step8 and step9 to persist install and start requestId
    * @param clusterStatus object with status, isCompleted, requestId, isInstallError and isStartError field.
    */
@@ -485,9 +509,9 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
   },
 
   save: function (name) {
-    var value = this.toObject(this.get('content.' + name));
-    this.setDBProperty(name, value);
-    console.log(this.get('name') + ": saved " + name, value);
+    var convertedValue = this.toJSInstance(this.get('content.' + name));
+    this.setDBProperty(name, convertedValue);
+    console.log(this.get('name') + ": saved " + name, convertedValue);
   },
 
   clear: function () {

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index 323db48..c5e3740 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1220,6 +1220,13 @@ Em.I18n.translations = {
 
   'admin.ra_highAvailability.wizard.header': 'Enable Ranger Admin HA Wizard',
   'admin.ra_highAvailability.wizard.step1.header': 'Get Started',
+  'admin.ra_highAvailability.wizard.step1.body': 'This wizard will walk you through enabling Ranger Admin HA on your cluster.<br/>' +
+  'Once enabled, you will be running a Standby Ranger Admin in addition to your Active Ranger Admin.<br/>' +
+  'This allows for an Active-Standby Ranger Admin configuration that automatically performs failover.<br/><br/>' +
+  '<b>You should plan a cluster maintenance window and prepare for cluster downtime when enabling Ranger Admin HA.</b><br/><br/>' +
+  'Please setup the load balancer and provide the URL to be used. Make sure that the load balancer is setup properly before proceeding.',
+  'admin.ra_highAvailability.wizard.step1.load_balancer_url': 'URL to load balancer',
+  'admin.ra_highAvailability.wizard.step1.invalid_url': 'Must be valid URL',
   'admin.ra_highAvailability.wizard.step2.header': 'Select Hosts',
   'admin.ra_highAvailability.wizard.step2.body': 'Select a host or hosts that will be running the additional Ranger Admin components',
   'admin.ra_highAvailability.wizard.step3.header': 'Review',

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/routes/ra_high_availability_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/ra_high_availability_routes.js b/ambari-web/app/routes/ra_high_availability_routes.js
index 3c076fe..01738f6 100644
--- a/ambari-web/app/routes/ra_high_availability_routes.js
+++ b/ambari-web/app/routes/ra_high_availability_routes.js
@@ -101,14 +101,15 @@ module.exports = App.WizardRoute.extend({
     route: '/step1',
     connectOutlets: function (router) {
       var controller = router.get('rAHighAvailabilityWizardController');
-      controller.setCurrentStep('1');
       controller.dataLoading().done(function () {
+        controller.setCurrentStep('1');
         controller.loadAllPriorSteps().done(function(){
           controller.connectOutlet('rAHighAvailabilityWizardStep1', controller.get('content'));
         });
       })
     },
     next: function (router) {
+      router.get('rAHighAvailabilityWizardController').save('loadBalancerURL');
       router.transitionTo('step2');
     }
   }),
@@ -117,8 +118,8 @@ module.exports = App.WizardRoute.extend({
     route: '/step2',
     connectOutlets: function (router) {
       var controller = router.get('rAHighAvailabilityWizardController');
-      controller.setCurrentStep('2');
       controller.dataLoading().done(function () {
+        controller.setCurrentStep('2');
         controller.loadAllPriorSteps().done(function(){
           controller.connectOutlet('rAHighAvailabilityWizardStep2', controller.get('content'));
         });
@@ -136,8 +137,8 @@ module.exports = App.WizardRoute.extend({
     route: '/step3',
     connectOutlets: function (router) {
       var controller = router.get('rAHighAvailabilityWizardController');
-      controller.setCurrentStep('3');
       controller.dataLoading().done(function () {
+        controller.setCurrentStep('3');
         controller.connectOutlet('rAHighAvailabilityWizardStep3', controller.get('content'));
       })
     },
@@ -153,8 +154,8 @@ module.exports = App.WizardRoute.extend({
     route: '/step4',
     connectOutlets: function (router) {
       var controller = router.get('rAHighAvailabilityWizardController');
-      controller.setCurrentStep('4');
       controller.dataLoading().done(function () {
+        controller.setCurrentStep('4');
         controller.connectOutlet('rAHighAvailabilityWizardStep4', controller.get('content'));
       })
     },

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/templates/main/admin/highAvailability/rangerAdmin/step1.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/highAvailability/rangerAdmin/step1.hbs b/ambari-web/app/templates/main/admin/highAvailability/rangerAdmin/step1.hbs
index bb7745d..b92d1c6 100644
--- a/ambari-web/app/templates/main/admin/highAvailability/rangerAdmin/step1.hbs
+++ b/ambari-web/app/templates/main/admin/highAvailability/rangerAdmin/step1.hbs
@@ -16,6 +16,25 @@ right ownership.  The ASF licenses this file
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
+<div>
+  <h2>{{t admin.ra_highAvailability.wizard.step1.header}}</h2>
+
+  <div class="alert alert-info">
+    {{t admin.ra_highAvailability.wizard.step1.body}}
+  </div>
+  <form class="form-horizontal">
+    <div {{bindAttr class=":control-group showloadBalancerURLError:error"}}>
+      <label class="control-label">{{t admin.ra_highAvailability.wizard.step1.load_balancer_url}}:</label>
+
+      <div class="controls">
+        {{view Em.TextField valueBinding="content.loadBalancerURL"}}
+        {{#if showloadBalancerURLError}}
+          <span class="help-inline">{{t admin.ra_highAvailability.wizard.step1.invalid_url}}</span>
+        {{/if}}
+      </div>
+    </div>
+  </form>
+</div>
 <div class="btn-area">
-  <a class="btn btn-success pull-right" {{action next}}>{{t common.next}} &rarr;</a>
+  <button class="btn btn-success pull-right" {{bindAttr disabled="isSubmitDisabled"}} {{action next}}>{{t common.next}} &rarr;</button>
 </div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/app/utils/validator.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/validator.js b/ambari-web/app/utils/validator.js
index fe7e286..00b02d9 100644
--- a/ambari-web/app/utils/validator.js
+++ b/ambari-web/app/utils/validator.js
@@ -223,5 +223,15 @@ module.exports = {
   isValidRackId: function(path) {
     // See app/message.js:hostPopup.setRackId.invalid
     return /^\/[/.\w-]+$/.test(path);
+  },
+
+  /**
+   * Validate url
+   * @param value
+   * @return {Boolean}
+   */
+  isValidURL: function(value) {
+    var urlRegex = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7
 FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i;
+    return urlRegex.test(value);
   }
 };

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/test/controllers/wizard_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/wizard_test.js b/ambari-web/test/controllers/wizard_test.js
index 79bfc5a..9b9c06f 100644
--- a/ambari-web/test/controllers/wizard_test.js
+++ b/ambari-web/test/controllers/wizard_test.js
@@ -308,4 +308,49 @@ describe('App.WizardController', function () {
     });
 
   });
+
+  describe('#toJSInstance', function () {
+
+    var testCases = [
+      {
+        o: {'test': 'test'},
+        e: {'test': 'test'}
+      },
+      {
+        o: {'test': Em.Object.create()},
+        e: {'test': {}}
+      },
+      {
+        o: {'test': Em.Object.create({'test': {}})},
+        e: {'test': {'test': {}}}
+      },
+      {
+        o: [],
+        e: []
+      },
+      {
+        o: Em.A([[]]),
+        e: [[]]
+      },
+      {
+        o: 11,
+        e: 11
+      },
+      {
+        o: '11',
+        e: '11'
+      },
+      {
+        o: null,
+        e: null
+      }
+    ];
+
+    it('should convert objects and arrays to pure JS objects and arrays', function () {
+      testCases.forEach(function (testCase) {
+        expect(c.toJSInstance(testCase.o)).to.eql(testCase.e);
+      });
+    });
+
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/2557d9a8/ambari-web/test/utils/validator_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/validator_test.js b/ambari-web/test/utils/validator_test.js
index bccb820..1ad5989 100644
--- a/ambari-web/test/utils/validator_test.js
+++ b/ambari-web/test/utils/validator_test.js
@@ -407,4 +407,21 @@ describe('validator', function () {
       })
     });
   });
+
+  describe('#isValidURL', function() {
+    var tests = [
+      {m:'"http://apache.org" - valid',i:'http://apache.org',e:true},
+      {m:'"http://ambari.apache.org" - valid',i:'http://ambari.apache.org',e:true},
+      {m:'"https://ambari.apache.org" - valid',i:'https://ambari.apache.org',e:true},
+      {m:'"htp://ambari.apache.org." - invalid',i:'.htp://ambari.apache.org.',e:false},
+      {m:'"ambari.apache.org" - invalid',i:'ambari.apache.org',e:false},
+      {m:'"www.ambari.apache.org" - invalid',i:'www.ambari.apache.org',e:false},
+      {m:'"" - invalid',i:'',e:false}
+    ];
+    tests.forEach(function(test) {
+      it(test.m + ' ', function () {
+        expect(validator.isValidURL(test.i)).to.equal(test.e);
+      })
+    });
+  });
 });