Repository: ambari
Updated Branches:
  refs/heads/trunk 34741fe38 -> 1fd8eb665


AMBARI-7721. UI: REST API Changes in Storm. (Buzhor Denys via onechiporenko)


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

Branch: refs/heads/trunk
Commit: 1fd8eb6658d22012535060cc42fbcf879795b854
Parents: 34741fe
Author: Oleg Nechiporenko <onechipore...@apache.org>
Authored: Fri Oct 10 14:01:33 2014 +0300
Committer: Oleg Nechiporenko <onechipore...@apache.org>
Committed: Fri Oct 10 14:01:33 2014 +0300

----------------------------------------------------------------------
 .../app/controllers/global/update_controller.js |   2 +-
 .../app/mappers/service_metrics_mapper.js       |  32 ++++--
 ambari-web/app/models/service/storm.js          |   2 +-
 ambari-web/app/utils/date.js                    |   2 +-
 ambari-web/app/utils/helper.js                  |  14 +++
 .../app/views/main/service/services/storm.js    |   5 +-
 .../global/update_controller_test.js            |  44 +++++++-
 ambari-web/test/mappers/service_mapper_test.js  | 108 +++++++++++++++++++
 ambari-web/test/utils/helper_test.js            | 106 ++++++++++++++++++
 9 files changed, 297 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js 
b/ambari-web/app/controllers/global/update_controller.js
index 35b9e13..8fb056e 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -410,7 +410,7 @@ App.UpdateController = Em.Controller.extend({
         "ServiceComponentInfo/GrayListedNodes," +
         "ServiceComponentInfo/BlackListedNodes," +
         "ServiceComponentInfo/jobtracker/*,",
-      'STORM': "metrics/api/cluster/summary,"
+      'STORM': /^2.1/.test(App.get('currentStackVersionNumber')) ? 
'metrics/api/cluster/summary' : 
'metrics/api/v1/cluster/summary,metrics/api/v1/topology/summary'
     };
     var services = App.cache['services'];
     services.forEach(function (service) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/app/mappers/service_metrics_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_metrics_mapper.js 
b/ambari-web/app/mappers/service_metrics_mapper.js
index 1ee93bc..1172381 100644
--- a/ambari-web/app/mappers/service_metrics_mapper.js
+++ b/ambari-web/app/mappers/service_metrics_mapper.js
@@ -18,6 +18,7 @@
 var App = require('app');
 var misc = require('utils/misc');
 var stringUtils = require('utils/string_utils');
+var dateUtils = require('utils/date');
 var previousResponse = [];
 
 App.serviceMetricsMapper = App.QuickDataMapper.create({
@@ -136,13 +137,13 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
     region_servers_total: 'region_servers_total'
   },
   stormConfig: {
-    total_tasks: 
'restApiComponent.metrics.api.cluster.summary.["tasks.total"]',
-    total_slots: 
'restApiComponent.metrics.api.cluster.summary.["slots.total"]',
-    free_slots: 'restApiComponent.metrics.api.cluster.summary.["slots.free"]',
-    used_slots: 'restApiComponent.metrics.api.cluster.summary.["tasks.total"]',
-    topologies: 'restApiComponent.metrics.api.cluster.summary.topologies',
-    total_executors: 
'restApiComponent.metrics.api.cluster.summary.["executors.total"]',
-    nimbus_uptime: 
'restApiComponent.metrics.api.cluster.summary.["nimbus.uptime"]',
+    total_tasks: 'restApiComponent.tasksTotal',
+    total_slots: 'restApiComponent.slotsTotal',
+    free_slots: 'restApiComponent.slotsFree',
+    used_slots: 'restApiComponent.slotsUsed',
+    topologies: 'restApiComponent.topologies',
+    total_executors: 'restApiComponent.executorsTotal',
+    nimbus_uptime: 'restApiComponent.nimbusUptime',
     super_visors_started: 'super_visors_started',
     super_visors_installed: 'super_visors_installed',
     super_visors_total: 'super_visors_total'
@@ -649,9 +650,22 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
   stormMapper: function(item) {
     var finalConfig = jQuery.extend({}, this.config);
     var stormConfig = this.stormConfig;
+    var metricsInfoComponent = 
/^2.1/.test(App.get('currentStackVersionNumber')) ? 'STORM_REST_API' : 
'STORM_UI_SERVER';
+    var metricsPath = {
+      STORM_REST_API: 'metrics.api.cluster.summary',
+      STORM_UI_SERVER: 'metrics.api.v1.cluster.summary'
+    }[metricsInfoComponent];
+
     item.components.forEach(function(component) {
-      if (component.ServiceComponentInfo && 
component.ServiceComponentInfo.component_name == "STORM_REST_API") {
-        item.restApiComponent = component;
+      if (component.ServiceComponentInfo && 
component.ServiceComponentInfo.component_name == metricsInfoComponent) {
+        if (Em.get(component, metricsPath)) {
+          item.restApiComponent = App.keysDottedToCamelCase(Em.get(component, 
metricsPath));
+          if (metricsInfoComponent == 'STORM_UI_SERVER') {
+            item.restApiComponent.topologies = Em.get(component, 
'metrics.api.v1.topology.summary.length');
+          } else {
+            item.restApiComponent.nimbusUptime = 
dateUtils.timingFormat(item.restApiComponent.nimbusUptime * 1000);
+          }
+        }
         finalConfig = jQuery.extend({}, finalConfig, stormConfig);
       }
     });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/app/models/service/storm.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service/storm.js 
b/ambari-web/app/models/service/storm.js
index f061d31..e4ede81 100644
--- a/ambari-web/app/models/service/storm.js
+++ b/ambari-web/app/models/service/storm.js
@@ -28,7 +28,7 @@ App.StormService = App.Service.extend({
   freeSlots: DS.attr('number'),
   totalExecutors: DS.attr('number'),
   topologies: DS.attr('number'),
-  nimbusUptime: DS.attr('number')
+  nimbusUptime: DS.attr('string')
 });
 
 App.StormService.FIXTURES = [];

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/app/utils/date.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/date.js b/ambari-web/app/utils/date.js
index 671ec02..73555b4 100644
--- a/ambari-web/app/utils/date.js
+++ b/ambari-web/app/utils/date.js
@@ -156,7 +156,7 @@ module.exports = {
    * 3500000 secs = 58.33 mins
    *
    * @param {number} time
-   * @param {bool} zeroValid for the case to show 0 when time is 0, not null
+   * @param {bool} [zeroValid] for the case to show 0 when time is 0, not null
    * @return {string|null} formatted date
    * @method timingFormat
    */

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/app/utils/helper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/helper.js b/ambari-web/app/utils/helper.js
index b5ce069..90d67eb 100644
--- a/ambari-web/app/utils/helper.js
+++ b/ambari-web/app/utils/helper.js
@@ -302,6 +302,20 @@ App.keysUnderscoreToCamelCase = function(object) {
   }
   return tmp;
 };
+
+/**
+ * Convert dotted keys to camelcase
+ *
+ * @param {Object} object
+ * @return {Object}
+ **/
+App.keysDottedToCamelCase = function(object) {
+  var tmp = {};
+  for (var key in object) {
+    tmp[key.split('.').reduce(function(p, c) { return p + c.capitalize()})] = 
object[key];
+  }
+  return tmp;
+};
 /**
  * Returns object with defined keys only.
  *

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/app/views/main/service/services/storm.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/service/services/storm.js 
b/ambari-web/app/views/main/service/services/storm.js
index 3546cd0..34242aa 100644
--- a/ambari-web/app/views/main/service/services/storm.js
+++ b/ambari-web/app/views/main/service/services/storm.js
@@ -44,9 +44,6 @@ App.MainDashboardServiceStormView = 
App.MainDashboardServiceView.extend({
   }.property('service.superVisorsTotal'),
 
   nimbusUptimeFormatted: function() {
-    if (this.get('service.nimbusUptime') > 0) {
-      return date.timingFormat(this.get('service.nimbusUptime')*1000);
-    }
-    return Em.I18n.t('services.service.summary.notRunning');
+    return this.get('service.nimbusUptime') || 
Em.I18n.t('services.service.summary.notRunning');
   }.property('service.nimbusUptime')
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/test/controllers/global/update_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/global/update_controller_test.js 
b/ambari-web/test/controllers/global/update_controller_test.js
index a880b1b..df4420e 100644
--- a/ambari-web/test/controllers/global/update_controller_test.js
+++ b/ambari-web/test/controllers/global/update_controller_test.js
@@ -200,15 +200,55 @@ describe('App.UpdateController', function () {
             }
           }
         ],
-        result: ["metrics/api/cluster/summary,"]
+        result: ["metrics/api/v1/cluster/summary," +
+          "metrics/api/v1/topology/summary"]
       }
     ];
 
+    var testCasesByStackVersion = [
+      {
+        title: 'STORM service stack 2.1',
+        services: [
+          {
+            ServiceInfo: {
+              service_name: 'STORM'
+            }
+          }
+        ],
+        stackVersionNumber: '2.1',
+        result: ["metrics/api/cluster/summary"]
+      },
+      {
+        title: 'STORM service stack 2.2',
+        services: [
+          {
+            ServiceInfo: {
+              service_name: 'STORM'
+            }
+          }
+        ],
+        stackVersionNumber: '2.2',
+        result: 
["metrics/api/v1/cluster/summary,metrics/api/v1/topology/summary"]
+      }
+    ];
     testCases.forEach(function(test){
       it(test.title, function () {
         App.cache['services'] = test.services;
         expect(controller.getConditionalFields()).to.eql(test.result);
       });
     });
+
+    testCasesByStackVersion.forEach(function(test) {
+      it(test.title, function() {
+        App.cache['services'] = test.services;
+        sinon.stub(App, 'get', function(key) {
+          if (key == 'currentStackVersionNumber') {
+            return test.stackVersionNumber;
+          }
+        });
+        expect(controller.getConditionalFields()).to.eql(test.result);
+        App.get.restore();
+      });
+    });
   });
-});
\ No newline at end of file
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/test/mappers/service_mapper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/mappers/service_mapper_test.js 
b/ambari-web/test/mappers/service_mapper_test.js
index e291ae7..1ab4cf9 100644
--- a/ambari-web/test/mappers/service_mapper_test.js
+++ b/ambari-web/test/mappers/service_mapper_test.js
@@ -85,4 +85,112 @@ describe('App.serviceMetricsMapper', function () {
     });
   });
 
+  describe('#stormMapper', function() {
+    var tests = [
+      {
+        stackVersionNumber: '2.2',
+        message: 'Storm mapper, stack version 2.2',
+        expectedValues: {
+          total_executors: 28,
+          nimbus_uptime: "15m 1s",
+          free_slots: 0,
+          used_slots: 2,
+          total_slots: 2,
+          total_tasks: 28,
+          topologies: 1
+        },
+        components: [
+          {
+            "ServiceComponentInfo" : {
+              "component_name" : "STORM_UI_SERVER",
+              "service_name" : "STORM"
+            },
+            "metrics" : {
+              "api" : {
+                "v1": {
+                  "cluster": {
+                    "summary": {
+                      "executorsTotal": 28.0,
+                      "nimbusUptime": "15m 1s",
+                      "slotsFree": 0.0,
+                      "slotsTotal": 2.0,
+                      "slotsUsed": 2.0,
+                      "supervisors": 1.0,
+                      "tasksTotal": 28.0
+                    }
+                  },
+                  "topology": {
+                    "summary": [
+                      {
+                        "executorsTotal": 21.0,
+                        "uptime": "5m 59s",
+                        "schedulerInfo": null,
+                        "name": "WordCountida8c06640_date2901141",
+                        "workersTotal": 2.0,
+                        "status": "ACTIVE",
+                        "owner": "",
+                        "tasksTotal": 21.0,
+                        "id": "WordCountida8c06640_date2901141-2-1412195707"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        ]
+      },
+      {
+        stackVersionNumber: '2.1',
+        message: 'Storm mapper, stack version 2.1',
+        expectedValues: {
+          total_executors: 2,
+          nimbus_uptime: "3.96 hours",
+          free_slots: 2,
+          used_slots: 0,
+          total_slots: 2,
+          total_tasks: 21,
+          topologies: 0
+        },
+        components: [
+          {
+            "ServiceComponentInfo" : {
+              "component_name" : "STORM_REST_API",
+              "service_name" : "STORM"
+            },
+            "metrics" : {
+              "api" : {
+                "cluster" : {
+                  "summary" : {
+                    "executors.total" : 2.0,
+                    "nimbus.uptime" : 14250.0,
+                    "slots.free" : 2.0,
+                    "slots.total" : 2.0,
+                    "slots.used" : 0.0,
+                    "supervisors" : 1.0,
+                    "tasks.total" : 21.0,
+                    "topologies" : 0.0
+                  }
+                }
+              }
+            }
+          }
+        ]
+      }
+    ];
+
+    tests.forEach(function(test) {
+      it(test.message, function() {
+        sinon.stub(App, 'get', function(key) {
+          if (key == 'currentStackVersionNumber') {
+            return test.stackVersionNumber;
+          }
+        });
+        var result = App.serviceMetricsMapper.stormMapper(test);
+        expect(result).to.include(test.expectedValues);
+        App.get.restore();
+      });
+    });
+
+  });
 });

http://git-wip-us.apache.org/repos/asf/ambari/blob/1fd8eb66/ambari-web/test/utils/helper_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/utils/helper_test.js 
b/ambari-web/test/utils/helper_test.js
index f75c1e4..9274ae0 100644
--- a/ambari-web/test/utils/helper_test.js
+++ b/ambari-web/test/utils/helper_test.js
@@ -318,7 +318,113 @@ describe('utils/helper', function() {
         expect(App.permit(obj, test.keys)).to.deep.eql(test.e);
       });
     });
+  });
 
+  describe('#App.keysUnderscoreToCamelCase()', function() {
+    var tests = [
+      {
+        object: {
+          'key_upper': '2'
+        },
+        expected: {
+          keyUpper: '2'
+        },
+        m: 'One level object, key should be camelCased'
+      },
+      {
+        object: {
+          'key_upper': '2',
+          'key': '1'
+        },
+        expected: {
+          keyUpper: '2',
+          key: '1'
+        },
+        m: 'One level object, one key should be camelCased.'
+      },
+      {
+        object: {
+          'key_upper': '2',
+          'key': '1'
+        },
+        expected: {
+          keyUpper: '2',
+          key: '1'
+        },
+        m: 'One level object, one key should be camelCased.'
+      },
+      {
+        object: {
+          'key_upper': '2',
+          'key_upone_uptwo_upthree': '4',
+          'key': '1'
+        },
+        expected: {
+          keyUpper: '2',
+          keyUponeUptwoUpthree: '4',
+          key: '1'
+        },
+        m: 'One level object, two keys should be camelCased, few dots 
notation.'
+      }
+    ];
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        
expect(App.keysUnderscoreToCamelCase(test.object)).to.deep.equal(test.expected);
+      });
+    });
+  });
 
+  describe('#App.keysDottedToCamelCase()', function() {
+    var tests = [
+      {
+        object: {
+          'key.upper': '2'
+        },
+        expected: {
+          keyUpper: '2'
+        },
+        m: 'One level object, key should be camelCased'
+      },
+      {
+        object: {
+          'key.upper': '2',
+          'key': '1'
+        },
+        expected: {
+          keyUpper: '2',
+          key: '1'
+        },
+        m: 'One level object, one key should be camelCased.'
+      },
+      {
+        object: {
+          'key.upper': '2',
+          'key': '1'
+        },
+        expected: {
+          keyUpper: '2',
+          key: '1'
+        },
+        m: 'One level object, one key should be camelCased.'
+      },
+      {
+        object: {
+          'key.upper': '2',
+          'key.upone.uptwo.upthree': '4',
+          'key': '1'
+        },
+        expected: {
+          keyUpper: '2',
+          keyUponeUptwoUpthree: '4',
+          key: '1'
+        },
+        m: 'One level object, two keys should be camelCased, few dots 
notation.'
+      }
+    ];
+    tests.forEach(function(test) {
+      it(test.m, function() {
+        
expect(App.keysDottedToCamelCase(test.object)).to.deep.equal(test.expected);
+      });
+    });
   });
 });

Reply via email to