Browse Source

AMBARI-1102. Error handling when errors are encountered during preparation for deploy. (Arun Kandregula via yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1431761 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 năm trước cách đây
mục cha
commit
69b6169cf9

+ 3 - 0
CHANGES.txt

@@ -458,6 +458,9 @@ AMBARI-666 branch (unreleased changes)
 
   IMPROVEMENTS
 
+  AMBARI-1102. Error handling when errors are encountered during preparation
+  for deploy. (Arun Kandregula via yusaku)
+
   AMBARI-1096. Create heatmap legend entries for missing data/invalid hosts.
   (Srimanth Gunturi via yusaku)
 

+ 1 - 0
ambari-web/app/controllers/wizard/step1_controller.js

@@ -60,6 +60,7 @@ App.WizardStep1Controller = Em.Controller.extend({
   submit: function () {
     this.set('hasSubmitted', true);
     if (!this.get('invalidClusterName')) {
+      App.clusterStatus.set('clusterName', this.get('content.cluster.name'));
       this.set('content.cluster.status', 'PENDING');
       this.set('content.cluster.isCompleted', false);
       App.router.send('next');

+ 1 - 0
ambari-web/app/controllers/wizard/step6_controller.js

@@ -198,6 +198,7 @@ App.WizardStep6Controller = Em.Controller.extend({
   renderSlaveHosts: function () {
     var hostsObj = Em.Set.create();
     var allHosts = this.getHostNames();
+    // TODO - Hard coding should be removed.
     var maxNoofHostComponents = 11;
     var slaveComponents = this.get('content.slaveComponentHosts');
 

+ 33 - 12
ambari-web/app/controllers/wizard/step8_controller.js

@@ -29,7 +29,7 @@ App.WizardStep8Controller = Em.Controller.extend({
   configMapping: require('data/config_mapping'),
   slaveComponentConfig: null,
   isSubmitDisabled: false,
-
+  hasErrorOccurred: false,
 
   selectedServices: function () {
     return this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false);
@@ -60,7 +60,9 @@ App.WizardStep8Controller = Em.Controller.extend({
       //TODO: Hive host depends on the type of db selected. Change puppet variable name if postgres is not the default db
       var hiveDb = globals.findProperty('name', 'hive_database');
       if (hiveDb.value === 'New MySQL Database') {
-        globals.findProperty('name', 'hive_ambari_host').name = 'hive_mysql_host';
+        if (globals.findProperty('name', 'hive_ambari_host')) {
+          globals.findProperty('name', 'hive_ambari_host').name = 'hive_mysql_host';
+        }
         globals = globals.without(globals.findProperty('name', 'hive_existing_host'));
         globals = globals.without(globals.findProperty('name', 'hive_existing_database'));
       } else {
@@ -724,6 +726,13 @@ App.WizardStep8Controller = Em.Controller.extend({
     this.set('isSubmitDisabled', true);
 
     if (App.testMode || !this.get('content.cluster.requestId')) {
+      // For recovery : set the cluster status
+      App.clusterStatus.set('value',{
+        clusterName: this.get('clusterName'),
+        clusterState: 'CLUSTER_DEPLOY_PREP_2',
+        localdb: App.db.data
+      });
+
       this.createCluster();
       this.createSelectedServices();
       //this.setAmbariUIDb();
@@ -1369,6 +1378,21 @@ App.WizardStep8Controller = Em.Controller.extend({
 
   },
 
+  registerErrPopup: function (header, message) {
+
+    App.ModalPopup.show({
+      header: header,
+      secondary: false,
+      onPrimary: function () {
+        this.hide();
+      },
+      bodyClass: Ember.View.extend({
+        template: Ember.Handlebars.compile(['<p>{{view.message}}</p>'].join('\n')),
+        message: message
+      })
+    });
+  },
+
   /**
    * We need to do a lot of ajax calls(about 10 or more) async in special order.
    * To do this i generate array of ajax objects and then send requests step by step.
@@ -1387,7 +1411,7 @@ App.WizardStep8Controller = Em.Controller.extend({
       timeout: App.timeout,
       error: function (request, ajaxOptions, error) {
         console.log('Step8: In Error ');
-        console.log('Step8: Error message is: ' + request.responseText);
+       // console.log('Step8: Error message is: ' + request.responseText);
       },
       success: function (data) {
         var jsonData = jQuery.parseJSON(data);
@@ -1404,20 +1428,17 @@ App.WizardStep8Controller = Em.Controller.extend({
       if (success) {
         success();
       }
-      ;
-      self.set('ajaxBusy', false);
-      self.doNextAjaxCall();
-    }
 
-    params.error = function () {
-      if (error) {
-        error();
-      }
-      ;
       self.set('ajaxBusy', false);
       self.doNextAjaxCall();
     }
 
+    params.error = function (xhr,status,error) {
+      var responseText = JSON.parse(xhr.responseText);
+        self.registerErrPopup("Error", responseText.message);
+        self.set('isSubmitDisabled',true);
+        self.set('hasErrorOccurred',true);
+    }
     this.get('ajaxQueue').pushObject(params);
   }
 

+ 1 - 0
ambari-web/app/models.js

@@ -22,6 +22,7 @@
 require('models/form'); // should be the 1st
 require('models/authentication');
 require('models/cluster');
+require('models/cluster_states');
 require('models/hosts');
 require('models/quick_links');
 require('models/service');

+ 105 - 0
ambari-web/app/models/cluster_states.js

@@ -0,0 +1,105 @@
+/**
+ * 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');
+
+  App.clusterStatus = Ember.Object.create({
+    clusterName: '',
+    validStates: ['CLUSTER_NOT_CREATED_1', 'CLUSTER_DEPLOY_PREP_2', 'CLUSTER_INSTALLING_3', 'CLUSTER_INSTALLED_4', 'CLUSTER_STARTED_5'],
+    clusterState: 'CLUSTER_NOT_CREATED_1',
+    localdb: null,
+    key: function () {
+      return 'CLUSTER_CURRENT_STATUS';
+    }.property(),
+    value: function (key, newValue) {
+      // getter
+      if (arguments.length == 1) {
+
+        var url = App.apiPrefix + '/persist/' + this.get('key');
+        jQuery.ajax(
+          {
+            url: url,
+            context: this,
+            async: false,
+            success: function (response) {
+              if (response) {
+                var newValue = jQuery.parseJSON(response);
+                if (newValue.clusterState)
+                  this.set('clusterState', newValue.clusterState);
+                if (newValue.clusterName)
+                  this.set('clusterName', newValue.clusterName);
+                if (newValue.localdb)
+                  this.set('localdb', newValue.localdb);
+              } else {
+                // default status already set
+              }
+            },
+            error: function (xhr) {
+              if (xhr.status == 404) {
+                // default status already set
+                console.log('Persist API did NOT find the key CLUSTER_CURRENT_STATUS');
+              }
+            }
+          }
+        );
+
+        return {
+          clusterName: this.get('clusterName'),
+          clusterState: this.get('clusterState'),
+          localdb: this.get('localdb')
+        };
+
+      } else if (newValue) {
+        //setter
+        if (newValue.clusterState) {
+          this.set('clusterState', newValue.clusterState);
+        }
+        if (newValue.clusterName) {
+          this.set('clusterName', newValue.clusterName);
+        }
+        if (newValue.localdb) {
+          this.set('localdb', newValue.localdb);
+        }
+
+        var url = App.apiPrefix + '/persist/';
+        var keyValuePair = {};
+        var val = {
+          clusterName: this.get('clusterName'),
+          clusterState: this.get('clusterState'),
+          localdb: this.get('localdb')
+        };
+        keyValuePair[this.get('key')] = JSON.stringify(val);
+
+
+        jQuery.ajax({
+          async: false,
+          context: this,
+          type: "POST",
+          url: url,
+          data: JSON.stringify(keyValuePair),
+          beforeSend: function () {
+            console.log('BeforeSend: persistKeyValues', keyValuePair);
+          }
+        });
+
+        return newValue;
+
+      }
+
+    }.property('clusterName', 'clusterState', 'localdb')
+
+  });

+ 2 - 3
ambari-web/app/router.js

@@ -247,9 +247,8 @@ App.Router = Em.Router.extend({
     if (App.alwaysGoToInstaller) {
       return 'installer';
     }
-    var clusterController = App.router.get('clusterController');
-    clusterController.loadClusterName(false);
-    if (clusterController.get('clusterName')) {
+    var clusterStatusOnServer = App.clusterStatus.get('value');
+    if (clusterStatusOnServer && clusterStatusOnServer.clusterState === 'CLUSTER_STARTED_5') {
       return 'main.index';
     } else {
       return 'installer';

+ 25 - 0
ambari-web/app/routes/installer.js

@@ -35,6 +35,23 @@ module.exports = Em.Route.extend({
         console.log('current step=' + router.get('installerController.currentStep'));
         Ember.run.next(function () {
           var installerController = router.get('installerController');
+
+            var currentClusterStatus = App.clusterStatus.get('value');
+
+            if (currentClusterStatus) {
+              switch (currentClusterStatus.clusterState) {
+                case 'CLUSTER_DEPLOY_PREP_2' :
+                  installerController.setCurrentStep('8');
+                  App.db.data = currentClusterStatus.localdb;
+                  break;
+                case 'CLUSTER_INSTALLING_3' :
+                  installerController.setCurrentStep('9');
+                  App.db.data = currentClusterStatus.localdb;
+                  break;
+                default:
+                  break;
+              }
+            }
           router.transitionTo('step' + installerController.get('currentStep'));
         });
       } else {
@@ -250,6 +267,14 @@ module.exports = Em.Route.extend({
       // invoke API call to install selected services
       installerController.installServices();
       installerController.setInfoForStep9();
+      // For recovery : set the cluster status
+      App.clusterStatus.set('value', {
+        clusterName: this.get('clusterName'),
+        clusterState: 'CLUSTER_INSTALLING_3',
+        localdb: App.db.data
+      });
+
+
       router.transitionTo('step9');
     }
   }),

+ 7 - 2
ambari-web/app/views/wizard/step8_view.js

@@ -27,8 +27,13 @@ App.WizardStep8View = Em.View.extend({
     var controller = this.get('controller');
     controller.loadStep();
   },
+  spinner : null,
 
   showLoadingIndicator: function(){
+    if(this.get('controller.hasErrorOccurred')){
+      $('.spinner').hide();
+      return;
+    }
     if(!this.get('controller.isSubmitDisabled')){
       return;
     }
@@ -51,7 +56,7 @@ App.WizardStep8View = Em.View.extend({
       left: 'auto' // Left position relative to parent in px
     };
     var target = $('#spinner')[0];
-    var spinner = new Spinner(opts).spin(target);
+    this.set('spinner', new Spinner(opts).spin(target));
 
     /*var el = $('#spinner').children('b');
     el.css('display', 'inline-block');
@@ -68,5 +73,5 @@ App.WizardStep8View = Em.View.extend({
       el.css('-moz-transform', 'rotate(' + deg + 'deg)');
       el.css('-webkit-transform', 'rotate(' + deg + 'deg)');
     }, 80);*/
-  }.observes('controller.isSubmitDisabled')
+  }.observes('controller.isSubmitDisabled','controller.hasErrorOccurred')
 });