Browse Source

AMBARI-5150. Ensure that the Server and Client versions match (browser caching issues). (xiwang via yusaku)

Yusaku Sako 11 years ago
parent
commit
6b6ce4330d

+ 29 - 0
ambari-web/app/controllers/installer.js

@@ -236,6 +236,35 @@ App.InstallerController = App.WizardController.extend({
     console.log('Error in loading stacks');
   },
 
+  /**
+   * check server version and web client version
+   */
+  checkServerClientVersion: function () {
+    var dfd = $.Deferred();
+    var self = this;
+    self.getServerVersion().done(function () {
+      dfd.resolve();
+    });
+    return dfd.promise();
+  },
+  getServerVersion: function(){
+    return App.ajax.send({
+      name: 'ambari.service.load_server_version',
+      sender: this,
+      success: 'getServerVersionSuccessCallback',
+      error: 'getServerVersionErrorCallback'
+    });
+  },
+  getServerVersionSuccessCallback: function (data) {
+    var clientVersion = App.get('version');
+    var serverVersion = (data.RootServiceComponents.component_version).toString();
+    this.set('versionConflictAlertBody', Em.I18n.t('app.versionMismatchAlert.body').format(serverVersion, clientVersion));
+    this.set('isServerClientVersionMismatch', clientVersion != serverVersion);
+  },
+  getServerVersionErrorCallback: function () {
+    console.log('ERROR: Cannot load Ambari server version');
+  },
+
   /**
    * Save data to model
    * @param stepController App.WizardStep4Controller

+ 30 - 0
ambari-web/app/controllers/main.js

@@ -119,5 +119,35 @@ App.MainController = Em.Controller.extend({
 
   stopAllService: function(event){
     App.router.get('mainServiceController').stopAllService(event);
+  },
+
+  /**
+   * check server version and web client version
+   */
+  checkServerClientVersion: function () {
+    var dfd = $.Deferred();
+    var self = this;
+    self.getServerVersion().done(function () {
+      dfd.resolve();
+    });
+    return dfd.promise();
+  },
+  getServerVersion: function(){
+    return App.ajax.send({
+      name: 'ambari.service.load_server_version',
+      sender: this,
+      success: 'getServerVersionSuccessCallback',
+      error: 'getServerVersionErrorCallback'
+    });
+  },
+  getServerVersionSuccessCallback: function (data) {
+    var clientVersion = App.get('version');
+    var serverVersion = (data.RootServiceComponents.component_version).toString();
+    this.set('versionConflictAlertBody', Em.I18n.t('app.versionMismatchAlert.body').format(serverVersion, clientVersion));
+    this.set('isServerClientVersionMismatch', clientVersion != serverVersion);
+  },
+  getServerVersionErrorCallback: function () {
+    console.log('ERROR: Cannot load Ambari server version');
   }
+
 });

+ 8 - 0
ambari-web/app/messages.js

@@ -24,6 +24,14 @@ Em.I18n.translations = {
   'app.reloadPopup.header': 'Reload Page',
 
   'app.loadingPlaceholder': 'Loading...',
+  'app.versionMismatchAlert.title': 'Ambari Server / Web Client Version Mismatch',
+  'app.versionMismatchAlert.body': 'Ambari Server and Web Client versions do not match:<br> ' +
+    '<br>Ambari Server: <strong>{0}</strong>' +
+    '<br>Ambari Web Client: <strong>{1}</strong><br>' +
+    '<br>This typically happens after upgrading Ambari due to Ambari Web Client code cached in the browser.' +
+    '<br>Perform hard refresh to see if this message disappears.' +
+    '<br>If you keep seeing this message, clear the browser cache completely and hit this URL again.' +
+    '<br>You must resolve this error in order to continue.',
   'app.signout':'Sign out',
   'app.settings':'Settings',
   'app.aboutAmbari':'About',

+ 53 - 48
ambari-web/app/routes/installer.js

@@ -28,55 +28,60 @@ module.exports = Em.Route.extend({
     App.clusterStatus.set('wizardControllerName',App.router.get('installerController.name'));
 
     if (router.getAuthenticated()) {
-      var name = 'Cluster Install Wizard';
-      $('title').text('Ambari - ' + name);
-
-      if (App.get('isAdmin')) {
-        router.get('mainController').stopPolling();
-        console.log('In installer with successful authenticated');
-        console.log('current step=' + router.get('installerController.currentStep'));
-        Ember.run.next(function () {
-          var installerController = router.get('installerController');
-
-          App.clusterStatus.updateFromServer();
-          var currentClusterStatus = App.clusterStatus.get('value');
-
-          if (currentClusterStatus) {
-            switch (currentClusterStatus.clusterState) {
-              case 'CLUSTER_NOT_CREATED_1' :
-                router.transitionTo('step' + installerController.get('currentStep'));
-                break;
-              case 'CLUSTER_DEPLOY_PREP_2' :
-                installerController.setCurrentStep('8');
-                App.db.data = currentClusterStatus.localdb;
-                router.transitionTo('step' + installerController.get('currentStep'));
-                break;
-              case 'CLUSTER_INSTALLING_3' :
-              case 'SERVICE_STARTING_3' :
-                if (!installerController.get('isStep9')) {
-                  installerController.setCurrentStep('9');
-                }
-                router.transitionTo('step' + installerController.get('currentStep'));
-                break;
-              case 'CLUSTER_INSTALLED_4' :
-                if (!installerController.get('isStep10')) {
-                  installerController.setCurrentStep('10');
-                }
-                App.db.data = currentClusterStatus.localdb;
-                router.transitionTo('step' + installerController.get('currentStep'));
-                break;
-              case 'DEFAULT' :
-              default:
-                router.transitionTo('main.dashboard');
-                break;
+      // check server/web client versions match
+      App.router.get('installerController').checkServerClientVersion().done(function() {
+
+        var name = 'Cluster Install Wizard';
+        $('title').text('Ambari - ' + name);
+
+        if (App.get('isAdmin')) {
+          router.get('mainController').stopPolling();
+          console.log('In installer with successful authenticated');
+          console.log('current step=' + router.get('installerController.currentStep'));
+          Ember.run.next(function () {
+            var installerController = router.get('installerController');
+
+            App.clusterStatus.updateFromServer();
+            var currentClusterStatus = App.clusterStatus.get('value');
+
+            if (currentClusterStatus) {
+              switch (currentClusterStatus.clusterState) {
+                case 'CLUSTER_NOT_CREATED_1' :
+                  router.transitionTo('step' + installerController.get('currentStep'));
+                  break;
+                case 'CLUSTER_DEPLOY_PREP_2' :
+                  installerController.setCurrentStep('8');
+                  App.db.data = currentClusterStatus.localdb;
+                  router.transitionTo('step' + installerController.get('currentStep'));
+                  break;
+                case 'CLUSTER_INSTALLING_3' :
+                case 'SERVICE_STARTING_3' :
+                  if (!installerController.get('isStep9')) {
+                    installerController.setCurrentStep('9');
+                  }
+                  router.transitionTo('step' + installerController.get('currentStep'));
+                  break;
+                case 'CLUSTER_INSTALLED_4' :
+                  if (!installerController.get('isStep10')) {
+                    installerController.setCurrentStep('10');
+                  }
+                  App.db.data = currentClusterStatus.localdb;
+                  router.transitionTo('step' + installerController.get('currentStep'));
+                  break;
+                case 'DEFAULT' :
+                default:
+                  router.transitionTo('main.dashboard');
+                  break;
+              }
             }
-          }
-        });
-      } else {
-        Em.run.next(function () {
-          App.router.transitionTo('main.services');
-        });
-      }
+          });
+        } else {
+          Em.run.next(function () {
+            App.router.transitionTo('main.services');
+          });
+        }
+
+      });
     } else {
       console.log('In installer but its not authenticated');
       console.log('value of authenticated is: ' + router.getAuthenticated());

+ 19 - 17
ambari-web/app/routes/main.js

@@ -23,24 +23,26 @@ module.exports = Em.Route.extend({
   route: '/main',
   enter: function (router) {
     App.db.updateStorage();
-    console.log('in /main:enter');
-    if (router.getAuthenticated()) {
-      App.router.get('mainAdminAccessController').loadShowJobsForUsers().done(function() {
-        App.router.get('clusterController').loadClusterName(false);
-        if(App.testMode) {
-          router.get('mainController').initialize();
-        }else {
-          App.router.get('clusterController').loadClientServerClockDistance().done(function() {
+      console.log('in /main:enter');
+      if (router.getAuthenticated()) {
+        App.router.get('mainAdminAccessController').loadShowJobsForUsers().done(function() {
+          App.router.get('clusterController').loadClusterName(false);
+          if(App.testMode) {
             router.get('mainController').initialize();
-          });
-        }
-      });
-      // TODO: redirect to last known state
-    } else {
-      Em.run.next(function () {
-        router.transitionTo('login');
-      });
-    }
+          }else {
+            App.router.get('mainController').checkServerClientVersion().done(function() {
+              App.router.get('clusterController').loadClientServerClockDistance().done(function() {
+                router.get('mainController').initialize();
+              });
+            });
+          }
+        });
+        // TODO: redirect to last known state
+      } else {
+        Em.run.next(function () {
+          router.transitionTo('login');
+        });
+      }
   },
   /*
    routePath: function(router,event) {

+ 6 - 0
ambari-web/app/styles/application.less

@@ -168,6 +168,12 @@ footer {
   }
 }
 
+#version-mismatch-title {
+  font-size: 18px;
+  font-weight: bold;
+  margin: 10px 0px 10px 0px;
+}
+
 #main-nav {
 
   li {

+ 34 - 26
ambari-web/app/templates/installer.hbs

@@ -15,34 +15,42 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
-
-<div class="wizard">
-  <div class="container">
-    <div class="container-fluid">
-      <div class="row-fluid">
-        <div class="span3">
-          <!--Sidebar content-->
-          <div class="well">
-            <ul class="nav nav-pills nav-stacked">
-              <li class="nav-header">{{t installer.header}}</li>
-              <li {{bindAttr class="isStep0:active view.isStep0Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep0 target="controller"}}>{{t installer.step0.header}}</a></li>
-              <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1 target="controller"}}>{{t installer.step1.header}}</a></li>
-              <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2 target="controller"}}>{{t installer.step2.header}}</a></li>
-              <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t installer.step3.header}}</a></li>
-              <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t installer.step4.header}}</a></li>
-              <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep5 target="controller"}}>{{t installer.step5.header}}</a></li>
-              <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep6 target="controller"}}>{{t installer.step6.header}}</a></li>
-              <li {{bindAttr class="isStep7:active view.isStep7Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep7 target="controller"}}>{{t installer.step7.header}}</a></li>
-              <li {{bindAttr class="isStep8:active view.isStep8Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep8 target="controller"}}>{{t installer.step8.header}}</a></li>
-              <li {{bindAttr class="isStep9:active view.isStep9Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep9 target="controller"}}>{{t installer.step9.header}}</a></li>
-              <li {{bindAttr class="isStep10:active view.isStep10Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep10 target="controller"}}>{{t installer.step10.header}}</a></li>
-            </ul>
+{{#if isServerClientVersionMismatch}}
+  <div id="version-mismatch-title">{{t app.versionMismatchAlert.title}}</div>
+  <div class="alert alert-danger">
+    {{{versionConflictAlertBody}}}
+  </div>
+{{else}}
+  <div class="wizard">
+    <div class="container">
+      <div class="container-fluid">
+        <div class="row-fluid">
+          <div class="span3">
+            <!--Sidebar content-->
+            <div class="well">
+              <ul class="nav nav-pills nav-stacked">
+                <li class="nav-header">{{t installer.header}}</li>
+                <li {{bindAttr class="isStep0:active view.isStep0Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep0 target="controller"}}>{{t installer.step0.header}}</a></li>
+                <li {{bindAttr class="isStep1:active view.isStep1Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep1 target="controller"}}>{{t installer.step1.header}}</a></li>
+                <li {{bindAttr class="isStep2:active view.isStep2Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep2 target="controller"}}>{{t installer.step2.header}}</a></li>
+                <li {{bindAttr class="isStep3:active view.isStep3Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep3 target="controller"}}>{{t installer.step3.header}}</a></li>
+                <li {{bindAttr class="isStep4:active view.isStep4Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep4 target="controller"}}>{{t installer.step4.header}}</a></li>
+                <li {{bindAttr class="isStep5:active view.isStep5Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep5 target="controller"}}>{{t installer.step5.header}}</a></li>
+                <li {{bindAttr class="isStep6:active view.isStep6Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep6 target="controller"}}>{{t installer.step6.header}}</a></li>
+                <li {{bindAttr class="isStep7:active view.isStep7Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep7 target="controller"}}>{{t installer.step7.header}}</a></li>
+                <li {{bindAttr class="isStep8:active view.isStep8Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep8 target="controller"}}>{{t installer.step8.header}}</a></li>
+                <li {{bindAttr class="isStep9:active view.isStep9Disabled:disabled"}}><a href="javascript:void(null);"  {{action gotoStep9 target="controller"}}>{{t installer.step9.header}}</a></li>
+                <li {{bindAttr class="isStep10:active view.isStep10Disabled:disabled"}}><a href="javascript:void(null);" {{action gotoStep10 target="controller"}}>{{t installer.step10.header}}</a></li>
+              </ul>
+            </div>
+          </div>
+          <div class="wizard-content well span9">
+            {{outlet}}
           </div>
-        </div>
-        <div class="wizard-content well span9">
-          {{outlet}}
         </div>
       </div>
     </div>
   </div>
-</div>
+{{/if}}
+
+

+ 13 - 11
ambari-web/app/templates/login.hbs

@@ -16,16 +16,18 @@
 * limitations under the License.
 }}
 
+{{#unless isServerClientVersionMismatch}}
 <div class="well login span4">
-    <h2>{{t login.header}}</h2>
-    {{#if errorMessage}}
-    <div class="alert alert-error">
-        {{errorMessage}}
-    </div>
-    {{/if}}
-    <label>{{t login.username}}</label>
-    {{view view.loginTextField valueBinding="loginName" class="span4"}}
-    <label>{{t common.password}}</label>
-    {{view view.passTextField type="password" valueBinding="password" class="span4"}}
-        <button class="btn btn-success" {{action "submit" target="controller"}}>{{t login.loginButton}}</button>
+  <h2>{{t login.header}}</h2>
+  {{#if errorMessage}}
+  <div class="alert alert-error">
+    {{errorMessage}}
+  </div>
+  {{/if}}
+  <label>{{t login.username}}</label>
+  {{view view.loginTextField valueBinding="loginName" class="span4"}}
+  <label>{{t common.password}}</label>
+  {{view view.passTextField type="password" valueBinding="password" class="span4"}}
+    <button class="btn btn-success" {{action "submit" target="controller"}}>{{t login.loginButton}}</button>
 </div>
+{{/unless}}

+ 23 - 14
ambari-web/app/templates/main.hbs

@@ -15,20 +15,29 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 }}
-
-{{#if isClusterDataLoaded}}
-  <div id="main-nav">
-    <div class="navbar">
-      <div class="navbar-inner">
-        {{view App.MainMenuView}}
+{{#if isServerClientVersionMismatch}}
+  <div id="version-mismatch-title">{{t app.versionMismatchAlert.title}}</div>
+  <div class="alert alert-danger">
+    {{{versionConflictAlertBody}}}
+  </div>
+{{else}}
+  {{#if isClusterDataLoaded}}
+    <div id="main-nav">
+      <div class="navbar">
+        <div class="navbar-inner">
+          {{view App.MainMenuView}}
+        </div>
       </div>
     </div>
-  </div>
-  {{outlet}}
+    {{outlet}}
+  {{/if}}
+  {{#unless isClusterDataLoaded}}
+    <h2>{{t app.loadingPlaceholder}} </h2>
+    <div class="progress progress-striped active">
+      <div class="bar" {{bindAttr style="controller.clusterDataLoadedPercent"}}></div>
+    </div>
+  {{/unless}}
 {{/if}}
-{{#unless isClusterDataLoaded}}
-  <h2>{{t app.loadingPlaceholder}} </h2>
-  <div class="progress progress-striped active">
-    <div class="bar" {{bindAttr style="controller.clusterDataLoadedPercent"}}></div>
-  </div>
-{{/unless}}
+
+
+

+ 5 - 0
ambari-web/app/utils/ajax.js

@@ -1389,6 +1389,10 @@ var urls = {
       };
     }
   },
+  'ambari.service.load_server_version': {
+    'real': '/services/AMBARI/components/AMBARI_SERVER?fields=RootServiceComponents/component_version',
+    'mock': ''
+  },
   'ambari.service': {
     'real': '/services/AMBARI/components/AMBARI_SERVER',
     'mock': '/data/services/ambari_server.json'
@@ -1397,6 +1401,7 @@ var urls = {
     'real': '/services/AMBARI/components/AMBARI_SERVER?fields=RootServiceComponents/server_clock',
     'mock': ''
   },
+
   'config_groups.create': {
     'real': '/clusters/{clusterName}/config_groups',
     'mock': '',

+ 0 - 1
ambari-web/app/views/login.js

@@ -33,5 +33,4 @@ App.LoginView = Em.View.extend({
       this.get("controller").submit();
     }
   })
-
 });