You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2013/02/27 21:37:39 UTC

svn commit: r1450948 - in /incubator/ambari/trunk/ambari-web/app: controllers/global/cluster_controller.js controllers/global/update_controller.js controllers/main.js initialize.js messages.js utils/updater.js

Author: yusaku
Date: Wed Feb 27 20:37:38 2013
New Revision: 1450948

URL: http://svn.apache.org/r1450948
Log:
AMBARI-1501. Nagios alerts do not update automatically. (yusaku)

Added:
    incubator/ambari/trunk/ambari-web/app/utils/updater.js
Modified:
    incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js
    incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js
    incubator/ambari/trunk/ambari-web/app/controllers/main.js
    incubator/ambari/trunk/ambari-web/app/initialize.js
    incubator/ambari/trunk/ambari-web/app/messages.js

Modified: incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js?rev=1450948&r1=1450947&r2=1450948&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/global/cluster_controller.js Wed Feb 27 20:37:38 2013
@@ -156,7 +156,7 @@ App.ClusterController = Em.Controller.ex
       var nagiosSvc = svcs.findProperty("serviceName", "NAGIOS");
       return nagiosSvc != null;
     }
-  }.property('App.router.updateController.isUpdated'),
+  }.property('App.router.updateController.isUpdated', 'dataLoadList.services'),
 
   /**
    * Sorted list of alerts.
@@ -181,109 +181,64 @@ App.ClusterController = Em.Controller.ex
   },
 
   /**
-   * This method automatically loads alerts when Nagios URL
-   * changes. Once done it will trigger dataLoadList.alerts
-   * property, which will trigger the alerts property.
+   * Load alerts from server
+   * @param callback Slave function, should be called to fire delayed update.
+   * Look at <code>App.updater.run</code> for more information.
+   * Also used to set <code>dataLoadList.alerts</code> status during app loading
    */
-  loadAlerts:function () {
-    if(App.Alert.find().content.length > 0){
-      return false;
-    }
-    var self=this;
-    if(App.router.get('updateController.isUpdated')){
-      return false;
-    }
-    var nagiosUrl = this.get('nagiosUrl');
-    if (nagiosUrl) {
-      var lastSlash = nagiosUrl.lastIndexOf('/');
-      if (lastSlash > -1) {
-        nagiosUrl = nagiosUrl.substring(0, lastSlash);
-      }
+  loadAlerts:function (callback) {
+    if (this.get('isNagiosInstalled')) {
       var dataUrl = this.getUrl('/data/alerts/alerts.json', '/host_components?fields=HostRoles/nagios_alerts&HostRoles/component_name=NAGIOS_SERVER');
+      var self = this;
       var ajaxOptions = {
         dataType:"json",
-        context:this,
-        complete:function (jqXHR, textStatus) {
-          self.updateLoadStatus('alerts');
+        complete:function () {
           self.updateAlerts();
+          callback();
         },
         error: function(jqXHR, testStatus, error) {
-          // this.showMessage(Em.I18n.t('nagios.alerts.unavailable'));
           console.log('Nagios $.ajax() response:', error);
         }
       };
       App.HttpClient.get(dataUrl, App.alertsMapper, ajaxOptions);
     } else {
-      this.updateLoadStatus('alerts');
       console.log("No Nagios URL provided.")
+      callback();
     }
-    return true;
-  }.observes('nagiosUrl'),
+  },
 
   /**
-   * Show message in UI
+   * Send request to server to load components updated statuses
+   * @param callback Slave function, should be called to fire delayed update.
+   * Look at <code>App.updater.run</code> for more information
+   * @return {Boolean} Whether we have errors
    */
-  showMessage: function(message){
-    App.ModalPopup.show({
-      header: 'Message',
-      body: message,
-      onPrimary: function() {
-        this.hide();
-      },
-      secondary : null
-    });
-  },
-
-  statusTimeoutId: null,
-
-  loadUpdatedStatusDelayed: function(delay){
-    delay = delay || App.componentsUpdateInterval;
-    var self = this;
-
-    this.set('statusTimeoutId',
-      setTimeout(function(){
-        self.loadUpdatedStatus();
-      }, delay)
-    );
-  },
-
-  loadUpdatedStatus: function(){
-
-    var timeoutId = this.get('statusTimeoutId');
-    if(timeoutId){
-      clearTimeout(timeoutId);
-      this.set('statusTimeoutId', null);
-    }
-
-    if(!this.get('isWorking')){
-      return false;
-    }
+  loadUpdatedStatus: function(callback){
 
     if(!this.get('clusterName')){
-      this.loadUpdatedStatusDelayed(this.get('componentsUpdateInterval')/2, 'error:clusterName');
-      return;
+      callback();
+      return false;
     }
     
     var servicesUrl = this.getUrl('/data/dashboard/services.json', '/services?fields=ServiceInfo,components/host_components/HostRoles/desired_state,components/host_components/HostRoles/state');
 
-    var self = this;
     App.HttpClient.get(servicesUrl, App.statusMapper, {
-      complete:function (jqXHR, textStatus) {
-        //console.log('Cluster Controller: Updated components statuses successfully!!!')
-        self.loadUpdatedStatusDelayed();
-      }
-    }, function(){
-      self.loadUpdatedStatusDelayed(null, 'error:response error');
+      complete: callback
     });
-
-  },
-  startLoadUpdatedStatus: function(){
-    var self = this;
-    this.set('isWorking', true);
-    setTimeout(function(){
-      self.loadUpdatedStatus();
-    }, App.componentsUpdateInterval*2);
+    return true;
   },
+
+  /**
+   * Start polling, when <code>isWorking</code> become true
+   */
+  startPolling: function(){
+    if(!this.get('isWorking')){
+      return false;
+    }
+    App.updater.run(this, 'loadUpdatedStatus', 'isWorking'); //update will not run it immediately
+    App.updater.run(this, 'loadAlerts', 'isWorking'); //update will not run it immediately
+    return true;
+  }.observes('isWorking'),
   /**
    *
    *  load all data and update load status
@@ -339,6 +294,10 @@ App.ClusterController = Em.Controller.ex
       self.updateLoadStatus('services');
     }, true);
 
+    this.loadAlerts(function(){
+      self.updateLoadStatus('alerts');
+    });
+
   },
 
   clusterName:function () {

Modified: incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js?rev=1450948&r1=1450947&r2=1450948&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/global/update_controller.js Wed Feb 27 20:37:38 2013
@@ -33,60 +33,21 @@ App.UpdateController = Em.Controller.ext
   },
 
   /**
-   * Wrapper for all updates
+   * Start polling, when <code>isWorking</code> become true
    */
   updateAll:function(){
     if(this.get('isWorking')) {
-      this.update('updateHost');
-      this.update('updateServiceMetric');
-      this.update('graphsUpdate');
+      App.updater.run(this, 'updateHost', 'isWorking');
+      App.updater.run(this, 'updateServiceMetric', 'isWorking');
+      App.updater.run(this, 'graphsUpdate', 'isWorking');
     }
   }.observes('isWorking'),
 
-  /**
-   * States for each update method (each field - method name)
-   */
-  states: {
-    'updateHost': null,
-    'updateServiceMetric': null,
-    'graphsUpdate': null
-  },
-
-  /**
-   * Callback for each update method
-   * @param {String} name - state name
-   * @return {Function}
-   */
-  updateCallback: function(name) {
-    var self = this;
-    return function() {
-      self.update(name);
-    }
-  },
-
-  /**
-   * Common method that executes provided by name update method (name from states object)
-   * @param {String} name - key in the states object
-   * @return {Boolean}
-   */
-  update: function(name) {
-    if(!this.get('isWorking')) {
-      return false;
-    }
-    clearTimeout(this.states[name]);
-    var self = this;
-    this.states[name] = setTimeout(function() {
-      self[name](self.updateCallback(name));
-    }, App.contentUpdateInterval);
-  },
-
   updateHost:function(callback) {
     var self = this;
       var hostsUrl = this.getUrl('/data/hosts/hosts.json', '/hosts?fields=Hosts/host_name,Hosts/public_host_name,Hosts/disk_info,Hosts/cpu_count,Hosts/total_mem,Hosts/host_status,Hosts/last_heartbeat_time,Hosts/os_arch,Hosts/os_type,Hosts/ip,host_components,metrics/disk,metrics/load/load_one');
       App.HttpClient.get(hostsUrl, App.hostsMapper, {
-        complete:function (jqXHR, textStatus) {
-          callback();
-        }
+        complete: callback
       });
   },
   graphs: [],
@@ -124,9 +85,7 @@ App.UpdateController = Em.Controller.ext
       self.set('isUpdated', true);
     };
       App.HttpClient.get(servicesUrl, App.servicesMapper, {
-        complete: function() {
-          callback();
-        }
+        complete: callback
       });
   }
 

Modified: incubator/ambari/trunk/ambari-web/app/controllers/main.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/controllers/main.js?rev=1450948&r1=1450947&r2=1450948&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/controllers/main.js (original)
+++ incubator/ambari/trunk/ambari-web/app/controllers/main.js Wed Feb 27 20:37:38 2013
@@ -46,7 +46,7 @@ App.MainController = Em.Controller.exten
   startPolling: function(){
     App.router.get('updateController').set('isWorking', true);
     App.router.get('backgroundOperationsController').set('isWorking', true);
-    App.router.get('clusterController').startLoadUpdatedStatus();
+    App.router.get('clusterController').set('isWorking', true);
   },
   stopPolling: function(){
     App.router.get('updateController').set('isWorking', false);

Modified: incubator/ambari/trunk/ambari-web/app/initialize.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/initialize.js?rev=1450948&r1=1450947&r2=1450948&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/initialize.js (original)
+++ incubator/ambari/trunk/ambari-web/app/initialize.js Wed Feb 27 20:37:38 2013
@@ -32,6 +32,7 @@ require('views');
 require('router');
 
 require('utils/ajax');
+require('utils/updater');
 
 require('mappers/server_data_mapper');
 require('mappers/status_mapper');

Modified: incubator/ambari/trunk/ambari-web/app/messages.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/messages.js?rev=1450948&r1=1450947&r2=1450948&view=diff
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/messages.js (original)
+++ incubator/ambari/trunk/ambari-web/app/messages.js Wed Feb 27 20:37:38 2013
@@ -888,8 +888,6 @@ Em.I18n.translations = {
   'apps.isRunning.popup.title':'Is running',
   'apps.isRunning.popup.content':'Job is running now',
 
-  'nagios.alerts.unavailable':'Alerts Unavailable',
-
   'menu.item.dashboard':'Dashboard',
   'menu.item.heatmaps':'Heatmaps',
   'menu.item.services':'Services',

Added: incubator/ambari/trunk/ambari-web/app/utils/updater.js
URL: http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-web/app/utils/updater.js?rev=1450948&view=auto
==============================================================================
--- incubator/ambari/trunk/ambari-web/app/utils/updater.js (added)
+++ incubator/ambari/trunk/ambari-web/app/utils/updater.js Wed Feb 27 20:37:38 2013
@@ -0,0 +1,100 @@
+/**
+ * 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');
+
+var states = {};
+
+function update(obj, name, isWorking){
+  if(typeof isWorking == 'string' && !obj.get(isWorking)){
+    return false;
+  }
+
+  var state = states[name];
+
+  if(!state){
+    var callback = function(){
+      update(obj, name, isWorking);
+    };
+    states[name] = state = {
+      timeout: null,
+      func: function(){
+        obj[name](callback);
+      },
+      callback: callback
+    };
+  }
+
+  clearTimeout(state.timeout);
+
+  state.timeout = setTimeout(state.func, App.contentUpdateInterval);
+  return true;
+};
+
+App.updater = {
+
+  /**
+   * Run function periodically with <code>App.contentUpdateInterval</code> delay.
+   * Example 1(wrong way, will not be working):
+   *    var obj = {
+   *      method: function(callback){
+   *        //do something
+   *      }
+   *    };
+   *    App.updater.run(obj, 'method');
+   *
+   * Will be called only once, because <code>callback</code> will never execute. Below is right way:
+   *
+   * Example 2:
+   *    var obj = {
+   *      method: function(callback){
+   *        //do something
+   *        callback();
+   *      }
+   *    };
+   *    App.updater.run(obj, 'method');
+   *
+   * Method will always be called.
+   *
+   * Example 3:
+   *    var obj = {
+   *      method: function(callback){
+   *          //do something
+   *          callback();
+   *      },
+   *      isWorking: true
+   *    };
+   *    App.updater.run(obj, 'method', 'isWorking');
+   *
+   * <code>obj.method</code> will be called automatically.
+   * Warning: You should call <code>callback</code> parameter when function finished iteration.
+   * Otherwise nothing happened next time.
+   * If <code>isWorking</code> provided, library will check <code>obj.isWorking</code> before iteration and
+   * stop working when it equals to false. Otherwise method will always be called.
+   *
+   *
+   *
+   * @param obj Object
+   * @param name Method name
+   * @param isWorking Property, which will be checked as a rule for working
+   * @return {*}
+   */
+  run: function(obj, name, isWorking){
+    return update(obj, name, isWorking);
+  }
+
+}