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 2016/02/11 10:47:58 UTC

ambari git commit: AMBARI-14992. Upon changing the time range for displaying graphs, UI does not show feedback (doesn't update and keeps showing the same graph) when data is not available (alexantonenko)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.2 e8f3ee9d9 -> 7ce5a0072


AMBARI-14992. Upon changing the time range for displaying graphs, UI does not show feedback (doesn't update and keeps showing the same graph) when data is not available (alexantonenko)


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

Branch: refs/heads/branch-2.2
Commit: 7ce5a0072259d8aa85258df5e9e1da0865a00692
Parents: e8f3ee9
Author: Alex Antonenko <hi...@gmail.com>
Authored: Wed Feb 10 15:45:50 2016 +0200
Committer: Alex Antonenko <hi...@gmail.com>
Committed: Thu Feb 11 11:47:54 2016 +0200

----------------------------------------------------------------------
 .../app/mixins/common/widgets/widget_mixin.js   |  49 +++++++-
 ambari-web/app/styles/application.less          |   5 +
 .../views/common/widget/graph_widget_view.js    |   4 +-
 .../test/mixins/common/widget_mixin_test.js     | 124 +++++++++++++++++++
 4 files changed, 176 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/7ce5a007/ambari-web/app/mixins/common/widgets/widget_mixin.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mixins/common/widgets/widget_mixin.js b/ambari-web/app/mixins/common/widgets/widget_mixin.js
index a6b13f2..6a2d287 100644
--- a/ambari-web/app/mixins/common/widgets/widget_mixin.js
+++ b/ambari-web/app/mixins/common/widgets/widget_mixin.js
@@ -121,6 +121,7 @@ App.WidgetMixin = Ember.Mixin.create({
           context: this,
           startCallName: 'getHostComponentMetrics',
           successCallback: this.getHostComponentMetricsSuccessCallback,
+          errorCallback: this.getMetricsErrorCallback,
           completeCallback: function () {
             requestCounter--;
             if (requestCounter === 0) this.onMetricsLoaded();
@@ -132,6 +133,7 @@ App.WidgetMixin = Ember.Mixin.create({
           context: this,
           startCallName: 'getServiceComponentMetrics',
           successCallback: this.getMetricsSuccessCallback,
+          errorCallback: this.getMetricsErrorCallback,
           completeCallback: function () {
             requestCounter--;
             if (requestCounter === 0) this.onMetricsLoaded();
@@ -273,12 +275,41 @@ App.WidgetMixin = Ember.Mixin.create({
         if (!Em.isNone(metric_data)) {
           _metric.data = metric_data;
           this.get('metrics').pushObject(_metric);
+        } else if (this.get('graphView')) {
+          var graph = this.get('childViews') && this.get('childViews').findProperty('_showMessage');
+          if (graph) {
+            graph.set('hasData', false);
+            this.set('isExportButtonHidden', true);
+            graph._showMessage('info', this.t('graphs.noData.title'), this.t('graphs.noDataAtTime.message'));
+            this.get('metrics').clear();
+          }
         }
       }, this);
     }
   },
 
   /**
+   * error callback on getting aggregated metrics and host component metrics
+   * @param {object} xhr
+   * @param {string} textStatus
+   * @param {string} errorThrown
+   */
+  getMetricsErrorCallback: function (xhr, textStatus, errorThrown) {
+    if (this.get('graphView')) {
+      var graph = this.get('childViews') && this.get('childViews').findProperty('_showMessage');
+      if (graph) {
+        if (xhr.readyState == 4 && xhr.status) {
+          textStatus = xhr.status + " " + textStatus;
+        }
+        graph.set('hasData', false);
+        this.set('isExportButtonHidden', true);
+        graph._showMessage('warn', this.t('graphs.error.title'), this.t('graphs.error.message').format(textStatus, errorThrown));
+        this.get('metrics').clear();
+      }
+    }
+  },
+
+  /**
    * make GET call to get metrics value for all host components
    * @param {object} request
    * @return {$.ajax}
@@ -708,6 +739,7 @@ App.WidgetLoadAggregator = Em.Object.create({
         bulks[id].subRequests = [{
           context: request.context,
           successCallback: request.successCallback,
+          errorCallback: request.errorCallback,
           completeCallback: request.completeCallback
         }];
       } else {
@@ -715,6 +747,7 @@ App.WidgetLoadAggregator = Em.Object.create({
         bulks[id].subRequests.push({
           context: request.context,
           successCallback: request.successCallback,
+          errorCallback: request.errorCallback,
           completeCallback: request.completeCallback
         });
       }
@@ -736,11 +769,17 @@ App.WidgetLoadAggregator = Em.Object.create({
           _request.subRequests.forEach(function (subRequest) {
             subRequest.successCallback.call(subRequest.context, response);
           }, this);
-        }).complete(function () {
-          _request.subRequests.forEach(function (subRequest) {
-            subRequest.completeCallback.call(subRequest.context);
-          }, this);
-        });
+        }).fail(function (xhr, textStatus, errorThrown) {
+            _request.subRequests.forEach(function (subRequest) {
+              if (subRequest.errorCallback) {
+                subRequest.errorCallback.call(subRequest.context, xhr, textStatus, errorThrown);
+              }
+            }, this);
+          }).complete(function () {
+              _request.subRequests.forEach(function (subRequest) {
+                subRequest.completeCallback.call(subRequest.context);
+              }, this);
+            });
       })(bulks[id]);
     }
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ce5a007/ambari-web/app/styles/application.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/application.less b/ambari-web/app/styles/application.less
index 9dff556..08736d8 100644
--- a/ambari-web/app/styles/application.less
+++ b/ambari-web/app/styles/application.less
@@ -2240,6 +2240,7 @@ a:focus {
       left: 60px;
       overflow: visible;
       position: relative;
+      text-align: center;
     }
     .chart-y-axis {
       position: absolute;
@@ -2255,6 +2256,10 @@ a:focus {
         margin-top: 35px !important;
       }
     }
+    .alert {
+      display: inline-block;
+      padding-right: 14px;
+    }
   }
   position: relative;
   margin: 20px 15px 0 15px;

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ce5a007/ambari-web/app/views/common/widget/graph_widget_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/widget/graph_widget_view.js b/ambari-web/app/views/common/widget/graph_widget_view.js
index 11abad9..5887e58 100644
--- a/ambari-web/app/views/common/widget/graph_widget_view.js
+++ b/ambari-web/app/views/common/widget/graph_widget_view.js
@@ -321,7 +321,9 @@ App.GraphWidgetView = Em.View.extend(App.WidgetMixin, App.ExportMetricsMixin, {
         self.set('parentView.isExportMenuHidden', true);
       });
       this.setYAxisFormatter();
-      this.loadData();
+      if (!arguments.length || this.get('parentView.data.length')) {
+        this.loadData();
+      }
       var self = this;
       Em.run.next(function () {
         if (self.get('isPreview')) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/7ce5a007/ambari-web/test/mixins/common/widget_mixin_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mixins/common/widget_mixin_test.js b/ambari-web/test/mixins/common/widget_mixin_test.js
index efc29af..73146c4 100644
--- a/ambari-web/test/mixins/common/widget_mixin_test.js
+++ b/ambari-web/test/mixins/common/widget_mixin_test.js
@@ -384,6 +384,129 @@ describe('App.WidgetMixin', function () {
       });
     });
   });
+
+  describe('#getMetricsErrorCallback()', function () {
+
+    var obj,
+      view = Em.Object.create({
+        _showMessage: Em.K
+      }),
+      cases = [
+        {
+          graphView: null,
+          metricsLength: 1,
+          showMessageCallCount: 0,
+          isExportButtonHidden: false,
+          title: 'no graph view'
+        },
+        {
+          graphView: {},
+          metricsLength: 1,
+          showMessageCallCount: 0,
+          isExportButtonHidden: false,
+          title: 'no childViews property'
+        },
+        {
+          graphView: {},
+          childViews: [],
+          metricsLength: 1,
+          showMessageCallCount: 0,
+          isExportButtonHidden: false,
+          title: 'no child views'
+        },
+        {
+          graphView: {},
+          childViews: [Em.Object.create({})],
+          metricsLength: 1,
+          showMessageCallCount: 0,
+          isExportButtonHidden: false,
+          title: 'no view with _showMessage method'
+        },
+        {
+          graphView: {},
+          childViews: [Em.Object.create({}), view],
+          metricsLength: 0,
+          showMessageCallCount: 1,
+          isExportButtonHidden: true,
+          title: 'graph view is available'
+        }
+      ],
+      messageCases = [
+        {
+          readyState: 2,
+          status: 0,
+          textStatus: 'error',
+          title: 'incomplete request'
+        },
+        {
+          readyState: 4,
+          status: 0,
+          textStatus: 'error',
+          title: 'no status code'
+        },
+        {
+          readyState: 4,
+          status: 404,
+          textStatus: '404 error',
+          title: 'status code available'
+        }
+      ];
+
+    beforeEach(function () {
+      sinon.spy(view, '_showMessage');
+    });
+
+    afterEach(function () {
+      view._showMessage.restore();
+    });
+
+    cases.forEach(function (item) {
+
+      describe(item.title, function () {
+
+        beforeEach(function () {
+          obj = Em.Object.create(App.WidgetMixin, {
+            metrics: [{}],
+            isExportButtonHidden: false,
+            graphView: item.graphView,
+            childViews: item.childViews
+          });
+          obj.getMetricsErrorCallback({});
+        });
+
+        it('metrics array', function () {
+          expect(obj.get('metrics')).to.have.length(item.metricsLength);
+        });
+
+        it('error message', function () {
+          expect(view._showMessage.callCount).to.equal(item.showMessageCallCount);
+        });
+
+        it('export button display', function () {
+          expect(obj.get('isExportButtonHidden')).to.equal(item.isExportButtonHidden);
+        });
+
+      });
+
+    });
+
+    messageCases.forEach(function (item) {
+
+      it(item.title, function () {
+        obj = Em.Object.create(App.WidgetMixin, {
+          graphView: Em.Object.create({}),
+          childViews: [view]
+        });
+        obj.getMetricsErrorCallback({
+          readyState: item.readyState,
+          status: item.status
+        }, 'error', 'Not Found');
+        expect(view._showMessage.firstCall.args).to.eql(['warn', Em.I18n.t('graphs.error.title'), Em.I18n.t('graphs.error.message').format(item.textStatus, 'Not Found')]);
+      });
+
+    });
+
+  });
 });
 
 
@@ -484,6 +607,7 @@ describe('App.WidgetLoadAggregator', function () {
       f1: function () {
         return {
           done: Em.K,
+          fail: Em.K,
           complete: Em.K
         }
       }