Browse Source

AMBARI-10648. Integrate Heatmap pages with widget and widget layout API. (jaimin)

Jaimin Jetly 10 năm trước cách đây
mục cha
commit
9639005f64
63 tập tin đã thay đổi với 968 bổ sung2369 xóa
  1. 6 6
      ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/widgets.json
  2. 2 2
      ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/widgets.json
  3. 2 2
      ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/widgets.json
  4. 1 1
      ambari-server/src/main/resources/stacks/HDP/2.0.6/widgets.json
  5. 6 6
      ambari-server/src/main/resources/stacks/HDP/2.3/services/HBASE/widgets.json
  6. 2 2
      ambari-web/app/assets/data/widget_layouts/HBASE/default_dashboard.json
  7. 258 0
      ambari-web/app/assets/data/widget_layouts/all_heatmaps.json
  8. 0 10
      ambari-web/app/assets/test/tests.js
  9. 0 19
      ambari-web/app/controllers.js
  10. 135 52
      ambari-web/app/controllers/main/charts/heatmap.js
  11. 2 86
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric.js
  12. 0 39
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO.js
  13. 0 45
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs.js
  14. 0 32
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread.js
  15. 0 32
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten.js
  16. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_gctime.js
  17. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_memHeapUsed.js
  18. 0 65
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused.js
  19. 0 46
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase.js
  20. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_compactionqueue.js
  21. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_memstoresize.js
  22. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_readrequest.js
  23. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_regions.js
  24. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_writerequest.js
  25. 0 63
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused.js
  26. 0 45
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_processrun.js
  27. 0 46
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn.js
  28. 0 66
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed.js
  29. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_gctime.js
  30. 0 29
      ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_memHeapUsed.js
  31. 1 32
      ambari-web/app/controllers/main/service/info/heatmap.js
  32. 4 111
      ambari-web/app/controllers/main/service/info/summary.js
  33. 0 17
      ambari-web/app/messages.js
  34. 2 1
      ambari-web/app/mixins.js
  35. 90 10
      ambari-web/app/mixins/common/widgets/widget_mixin.js
  36. 146 0
      ambari-web/app/mixins/common/widgets/widget_section.js
  37. 2 0
      ambari-web/app/models/widget.js
  38. 8 4
      ambari-web/app/routes/main.js
  39. 39 0
      ambari-web/app/templates/common/widget/heatmap_widget.hbs
  40. 27 51
      ambari-web/app/templates/main/charts/heatmap.hbs
  41. 38 0
      ambari-web/app/templates/main/charts/heatmap_dropdown.hbs
  42. 32 0
      ambari-web/app/templates/main/service/info/heatmap_dropdown.hbs
  43. 10 0
      ambari-web/app/utils/ajax/ajax.js
  44. 1 1
      ambari-web/app/utils/heatmap.js
  45. 1 0
      ambari-web/app/views.js
  46. 116 0
      ambari-web/app/views/common/widget/heatmap_widget_view.js
  47. 5 2
      ambari-web/app/views/main/charts/heatmap.js
  48. 5 0
      ambari-web/app/views/main/charts/heatmap/heatmap_host.js
  49. 1 90
      ambari-web/app/views/main/charts/heatmap/heatmap_rack.js
  50. 3 1
      ambari-web/app/views/main/service/info/heatmap_view.js
  51. 1 1
      ambari-web/app/views/main/service/info/summary.js
  52. 0 113
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO_test.js
  53. 0 45
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread_test.js
  54. 0 45
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten_test.js
  55. 0 115
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_test.js
  56. 0 116
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused_test.js
  57. 0 125
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_test.js
  58. 0 136
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused_test.js
  59. 0 111
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_processrun_test.js
  60. 0 43
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_test.js
  61. 0 128
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed_test.js
  62. 0 115
      ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_test.js
  63. 22 30
      ambari-web/test/controllers/main/charts/heatmap_test.js

+ 6 - 6
ambari-server/src/main/resources/common-services/HBASE/0.96.0.2.0/widgets.json

@@ -139,7 +139,7 @@
           "is_visible": true,
           "metrics": [
             {
-              "name": "ipc.IPC.numOpenConnections",
+              "name": "regionserver.RegionServer.numOpenConnections",
               "metric_path": "metrics/hbase/ipc/IPC/numOpenConnections",
               "category": "",
               "service_name": "HBASE",
@@ -149,7 +149,7 @@
           "values": [
             {
               "name": "Open Connections",
-              "value": "${ipc.IPC.numOpenConnections}"
+              "value": "${regionserver.RegionServer.numOpenConnections}"
             }
           ],
           "properties": {
@@ -165,13 +165,13 @@
           "is_visible": true,
           "metrics": [
             {
-              "name": "ipc.IPC.numActiveHandler",
+              "name": "regionserver.RegionServer.numActiveHandler",
               "metric_path": "metrics/hbase/ipc/IPC/numActiveHandler",
               "service_name": "HBASE",
               "component_name": "HBASE_REGIONSERVER"
             },
             {
-              "name": "ipc.IPC.numCallsInGeneralQueue",
+              "name": "regionserver.RegionServer.numCallsInGeneralQueue",
               "metric_path": "metrics/hbase/ipc/IPC/numCallsInGeneralQueue",
               "service_name": "HBASE",
               "component_name": "HBASE_REGIONSERVER"
@@ -180,11 +180,11 @@
           "values": [
             {
               "name": "Active Handlers",
-              "value": "${ipc.IPC.numActiveHandler}"
+              "value": "${regionserver.RegionServer.numActiveHandler}"
             },
             {
               "name": "Calls in General Queue",
-              "value": "${ipc.IPC.numCallsInGeneralQueue}"
+              "value": "${regionserver.RegionServer.numCallsInGeneralQueue}"
             }
           ],
           "properties": {

+ 2 - 2
ambari-server/src/main/resources/common-services/HDFS/2.1.0.2.0/widgets.json

@@ -7,7 +7,7 @@
       "widgetLayoutInfo": [
         {
           "widget_name": "GC_STATISTICS",
-          "display_name": "Garbage Collection Statistics",
+          "display_name": "GC Statistics",
           "description": "This widget shows JVM Garbage collection statistics for Active NameNode",
           "widget_type": "GRAPH",
           "is_visible": true,
@@ -287,7 +287,7 @@
           "metrics": [
             {
               "name": "dfs.datanode.BytesWritten",
-              "metric_path": "metrics/dfs/datanode/bytes_read",
+              "metric_path": "metrics/dfs/datanode/bytes_written",
               "service_name": "HDFS",
               "component_name": "DATANODE"
             }

+ 2 - 2
ambari-server/src/main/resources/common-services/YARN/2.1.0.2.0/widgets.json

@@ -210,7 +210,7 @@
         },
         {
           "widget_name": "YARN_MEMORY_USED",
-          "display_name": "YARN Memory used %",
+          "display_name": "NodeManager Memory used %",
           "description": "",
           "widget_type": "HEATMAP",
           "is_visible": false,
@@ -230,7 +230,7 @@
           ],
           "values": [
             {
-              "name": "YARN Memory used %",
+              "name": "NodeManager Memory used %",
               "value": "${yarn.NodeManagerMetrics.AllocatedGB/(yarn.NodeManagerMetrics.AvailableGB + yarn.NodeManagerMetrics.AllocatedGB)}"
             }
           ],

+ 1 - 1
ambari-server/src/main/resources/stacks/HDP/2.0.6/widgets.json

@@ -3,7 +3,7 @@
     {
       "layout_name": "default_system_heatmap",
       "display_name": "Heatmaps",
-      "section_name": "SYSTEM_METRICS_HEATMAPS",
+      "section_name": "SYSTEM_HEATMAPS",
       "widgetLayoutInfo": [
         {
           "widget_name": "HOST_DISK_USED",

+ 6 - 6
ambari-server/src/main/resources/stacks/HDP/2.3/services/HBASE/widgets.json

@@ -145,7 +145,7 @@
           "is_visible": true,
           "metrics": [
             {
-              "name": "ipc.IPC.numOpenConnections",
+              "name": "regionserver.RegionServer.numOpenConnections",
               "metric_path": "metrics/hbase/ipc/IPC/numOpenConnections",
               "category": "",
               "service_name": "HBASE",
@@ -155,7 +155,7 @@
           "values": [
             {
               "name": "Open Connections",
-              "value": "${ipc.IPC.numOpenConnections}"
+              "value": "${regionserver.RegionServer.numOpenConnections}"
             }
           ],
           "properties": {
@@ -171,13 +171,13 @@
           "is_visible": true,
           "metrics": [
             {
-              "name": "ipc.IPC.numActiveHandler",
+              "name": "regionserver.RegionServer.numActiveHandler",
               "metric_path": "metrics/hbase/ipc/IPC/numActiveHandler",
               "service_name": "HBASE",
               "component_name": "HBASE_REGIONSERVER"
             },
             {
-              "name": "ipc.IPC.numCallsInGeneralQueue",
+              "name": "regionserver.RegionServer.numCallsInGeneralQueue",
               "metric_path": "metrics/hbase/ipc/IPC/numCallsInGeneralQueue",
               "service_name": "HBASE",
               "component_name": "HBASE_REGIONSERVER"
@@ -186,11 +186,11 @@
           "values": [
             {
               "name": "Active Handlers",
-              "value": "${ipc.IPC.numActiveHandler}"
+              "value": "${regionserver.RegionServer.numActiveHandler}"
             },
             {
               "name": "Calls in General Queue",
-              "value": "${ipc.IPC.numCallsInGeneralQueue}"
+              "value": "${regionserver.RegionServer.numCallsInGeneralQueue}"
             }
           ],
           "properties": {

+ 2 - 2
ambari-web/app/assets/data/widget_layouts/HBASE/default_dashboard.json

@@ -36,7 +36,7 @@
               "author": "ambari",
               "description": "This widget shows 95th percentile of the read latency.",
               "scope": "CLUSTER",
-              "properties": "{\"display_unit\":\"%\"}",
+              "properties": "{\"display_unit\":\"\"}",
               "widget_name": "READ_LATENCY_95",
               "widget_type": "NUMBER",
               "time_created": 1428990958952,
@@ -53,7 +53,7 @@
               "author": "ambari",
               "description": "This widget shows 95th percentile of the write latency.",
               "scope": "CLUSTER",
-              "properties": "{\"display_unit\":\"%\"}",
+              "properties": "{\"display_unit\":\"\"}",
               "widget_name": "WRITE_LATENCY_95",
               "widget_type": "NUMBER",
               "time_created": 1428990958952,

+ 258 - 0
ambari-web/app/assets/data/widget_layouts/all_heatmaps.json

@@ -0,0 +1,258 @@
+
+{
+  "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets?WidgetInfo/widget_type=HEATMAP&WidgetInfo/scope=CLUSTER",
+  "items" : [
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/1",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "Host Disk Space Used %",
+        "id" : 1,
+        "scope" : "CLUSTER",
+        "widget_name" : "HOST_DISK_USED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/2",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "Host Memory Used %",
+        "id" : 2,
+        "scope" : "CLUSTER",
+        "widget_name" : "HOST_MEMORY_USED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/3",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "Host CPU Wait IO %",
+        "id" : 3,
+        "scope" : "CLUSTER",
+        "widget_name" : "HOST_CPU_WAIT_IO",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/12",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HDFS Bytes Read",
+        "id" : 12,
+        "scope" : "CLUSTER",
+        "widget_name" : "HDFS_BYTES_READ",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/13",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HDFS Bytes Written",
+        "id" : 13,
+        "scope" : "CLUSTER",
+        "widget_name" : "HDFS_BYTES_WRITE",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/14",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "DataNode Garbage Collection Time",
+        "id" : 14,
+        "scope" : "CLUSTER",
+        "widget_name" : "DN_GC_TIME",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/15",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "DataNode JVM Heap Memory Used",
+        "id" : 15,
+        "scope" : "CLUSTER",
+        "widget_name" : "DN_JVM_HEAP_USED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/16",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "DataNode JVM Heap Memory Committed",
+        "id" : 16,
+        "scope" : "CLUSTER",
+        "widget_name" : "DN_JVM_HEAP_COMMITTED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/17",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "DataNode Process Disk I/O Utilization",
+        "id" : 17,
+        "scope" : "CLUSTER",
+        "widget_name" : "DN_DISK_IO",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/18",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "DataNode Process Network I/O Utilization",
+        "id" : 18,
+        "scope" : "CLUSTER",
+        "widget_name" : "DN_NETWORK_IO",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/23",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "NodeManager Garbage Collection Time",
+        "id" : 23,
+        "scope" : "CLUSTER",
+        "widget_name" : "NM_GC_TIME",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/24",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "NodeManager JVM Heap Memory Used",
+        "id" : 24,
+        "scope" : "CLUSTER",
+        "widget_name" : "NM_JVM_Heap_Used",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/25",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "YARN Memory used %",
+        "id" : 25,
+        "scope" : "CLUSTER",
+        "widget_name" : "YARN_MEMORY_USED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/26",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "Allocated Containers",
+        "id" : 26,
+        "scope" : "CLUSTER",
+        "widget_name" : "ALLOCATED_CONTAINER",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/27",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "NodeManager RAM Utilized",
+        "id" : 27,
+        "scope" : "CLUSTER",
+        "widget_name" : "NM_RAM_UTILIZED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/28",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "NodeManager CPU Utilized",
+        "id" : 28,
+        "scope" : "CLUSTER",
+        "widget_name" : "NM_CPU_UTILIZED",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/37",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HBase Compaction Queue Size",
+        "id" : 37,
+        "scope" : "CLUSTER",
+        "widget_name" : "HBASE_COMPACTION_QUEUE_SIZE",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/38",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HBase Memstore Sizes",
+        "id" : 38,
+        "scope" : "CLUSTER",
+        "widget_name" : "HBASE_MEMSTORE_SIZES",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/39",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HBase Read Request Count",
+        "id" : 39,
+        "scope" : "CLUSTER",
+        "widget_name" : "HBASE_READ_REQUEST",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/40",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HBase Write Request Count",
+        "id" : 40,
+        "scope" : "CLUSTER",
+        "widget_name" : "HBASE_WRITE_REQUEST",
+        "widget_type" : "HEATMAP"
+      }
+    },
+    {
+      "href" : "http://104.196.82.37:8080/api/v1/clusters/c1/widgets/41",
+      "WidgetInfo" : {
+        "author" : "ambari",
+        "cluster_name" : "c1",
+        "display_name" : "HBase Regions",
+        "id" : 41,
+        "scope" : "CLUSTER",
+        "widget_name" : "HBASE_REGIONS",
+        "widget_type" : "HEATMAP"
+      }
+    }
+  ]
+}

+ 0 - 10
ambari-web/app/assets/test/tests.js

@@ -73,16 +73,6 @@ var files = ['test/init_model_test',
   'test/controllers/main/dashboard/config_history_controller_test',
   'test/controllers/main/charts/heatmap_test',
   'test/controllers/main/charts/heatmap_metrics/heatmap_metric_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed_test',
-  'test/controllers/main/charts/heatmap_metrics/heatmap_metric_processrun_test',
   'test/controllers/main/alerts/manage_alert_groups_controller_test',
   'test/controllers/main/host/add_controller_test',
   'test/controllers/main/host/configs_service_test',

+ 0 - 19
ambari-web/app/controllers.js

@@ -118,25 +118,6 @@ require('controllers/main/host/addHost/step4_controller');
 require('controllers/main/host/host_alerts_controller');
 require('controllers/main/charts');
 require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_processrun');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_gctime');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_memHeapUsed');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_gctime');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_memHeapUsed');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_readrequest');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_writerequest');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_compactionqueue');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_regions');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_memstoresize');
 require('controllers/main/charts/heatmap');
 require('controllers/main/service/info/heatmap');
 require('controllers/main/views_controller');

+ 135 - 52
ambari-web/app/controllers/main/charts/heatmap.js

@@ -17,35 +17,148 @@
 
 var App = require('app');
 
-App.MainChartsHeatmapController = Em.Controller.extend({
+App.MainChartsHeatmapController = Em.Controller.extend(App.WidgetSectionMixin, {
   name: 'mainChartsHeatmapController',
-  rackMap: [],
-  modelRacks: [],
+  rackMap: {},
+  racks: [],
   rackViews: [],
+
+  /**
+   * Heatmap metrics that are available choices  on the page
+   */
+  heatmapCategories: [],
+
+  allHeatmaps:[],
+
+  layoutNameSuffix: "_heatmap",
+
+  sectionNameSuffix: "_HEATMAPS",
+
   loadRacksUrlParams: 'fields=Hosts/rack_info,Hosts/host_name,Hosts/public_host_name,Hosts/os_type,Hosts/ip,host_components,metrics/disk,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free&minimal_response=true',
 
-  racks: function () {
-    return this.get('modelRacks');
-  }.property('modelRacks.@each.isLoaded'),
+  loadHeatmapsUrlParams: function() {
+    var serviceName = this.get('content.serviceName');
+    if (serviceName) {
+      return 'WidgetInfo/widget_type=HEATMAP&WidgetInfo/scope=CLUSTER&WidgetInfo/metrics.matches(.*\"service_name\":\"' + serviceName + '\".*)&fields=WidgetInfo/metrics';
+    } else {
+      return 'WidgetInfo/widget_type=HEATMAP&WidgetInfo/scope=CLUSTER&fields=WidgetInfo/metrics';
+    }
+  }.property('content.serviceName'),
+
+
+  selectedMetric: null,
+
+  inputMaximum: '',
+
+  /**
+   * Heatmap widget currently shown on the page
+   */
+  activeWidget: function() {
+    if (this.get('widgets') && this.get('widgets').length) {
+      return this.get('widgets')[0];
+    } else {
+      return false;
+    }
+  }.property('widgets.@each'),
+
+
+  /**
+   * This function is called from the binded view of the controller
+   */
+  loadPageData: function() {
+    var self = this;
+    this.resetPageData();
+    this.getAllHeatMaps().done(function(allHeatmapData){
+      allHeatmapData.items.forEach(function(_allHeatmapData) {
+        self.get('allHeatmaps').pushObject(_allHeatmapData.WidgetInfo);
+      });
+      var categories = self.categorizeByServiceName(self.get('allHeatmaps'));
+      self.set('heatmapCategories', categories);
+      self.loadActiveWidgetLayout();
+    });
+  },
+
+  /**
+   * categorize heatmaps with respect to service names
+   * @param {Array} allHeatmaps
+   * @return {Array}
+   */
+  categorizeByServiceName: function(allHeatmaps) {
+  var categories = [];
+    allHeatmaps.forEach(function(_heatmap){
+    var serviceNames = JSON.parse(_heatmap.metrics).mapProperty('service_name').uniq();
+      serviceNames.forEach(function(_serviceName){
+        var category = categories.findProperty('serviceName',_serviceName);
+        if (!category) {
+          categories.pushObject(Em.Object.create({
+            serviceName: _serviceName,
+            displayName: _serviceName === 'STACK' ? 'Host' : App.StackService.find().findProperty('serviceName',_serviceName).get('displayName'),
+            heatmaps: [_heatmap]
+          }));
+        } else {
+          category.get('heatmaps').pushObject(_heatmap);
+        }
+      },this);
+    },this);
+    return categories;
+  },
+
+  /**
+   * clears/resets the data. This function should be called every time user navigates to heatmap page
+   */
+  resetPageData: function() {
+    this.get('heatmapCategories').clear();
+    this.get('allHeatmaps').clear();
+  },
+
+  /**
+   * success callback of <code>loadActiveWidgetLayout()</code>
+   * @overrriden
+   * @param {object|null} data
+   */
+  loadActiveWidgetLayoutSuccessCallback: function (data) {
+    if (data.items[0]) {
+      App.widgetMapper.map(data.items[0].WidgetLayoutInfo);
+      App.widgetLayoutMapper.map(data);
+      this.set('activeWidgetLayout', App.WidgetLayout.find().findProperty('layoutName', this.get('defaultLayoutName')));
+      this.set('isWidgetsLoaded', true);
+    }
+  },
+
+  /**
+   *  Gets all heatmap widgets that should be available in select metrics dropdown on heatmap page
+   * @return {$.ajax}
+   */
+  getAllHeatMaps: function() {
+    var urlParams = this.get('loadHeatmapsUrlParams');
+
+    return App.ajax.send({
+      name: 'widgets.get',
+      sender: this,
+      data: {
+        urlParams: urlParams
+      }
+    });
+  },
+
 
   /**
    * get hosts from server
    */
   loadRacks: function () {
-    this.get('modelRacks').clear();
-    this.get('rackMap').clear();
+    this.get('racks').clear();
+    this.set('rackMap', {});
     var urlParams = this.get('loadRacksUrlParams');
-    App.ajax.send({
+    return App.ajax.send({
       name: 'hosts.heatmaps',
       sender: this,
       data: {
         urlParams: urlParams
-      },
-      success: 'getHostsSuccessCallback'
+      }
     });
   },
 
-  getHostsSuccessCallback: function (data, opt, params) {
+  loadRacksSuccessCallback: function (data, opt, params) {
     var hosts = [];
     data.items.forEach(function (item) {
       hosts.push({
@@ -64,14 +177,14 @@ App.MainChartsHeatmapController = Em.Controller.extend({
       });
     });
     var rackMap = this.indexByRackId(hosts);
-    var modelRacks = this.toList(rackMap);
+    var racks = this.toList(rackMap);
     //this list has an empty host array property
     this.set('rackMap', rackMap);
-    this.set('modelRacks', modelRacks);
+    this.set('racks', racks);
   },
 
   indexByRackId: function (hosts) {
-    var rackMap = [];
+    var rackMap = {};
     hosts.forEach(function (host) {
       var rackId = host.rack;
       if(!rackMap[rackId]) {
@@ -97,7 +210,7 @@ App.MainChartsHeatmapController = Em.Controller.extend({
           Em.Object.create({
             name: rackKey,
             rackId: rackKey,
-            hosts: [],
+            hosts: rackMap[rackKey].hosts,
             isLoaded: false,
             index: i++
           })
@@ -107,25 +220,6 @@ App.MainChartsHeatmapController = Em.Controller.extend({
     return racks;
   },
 
-  allMetrics: function () {
-    var metrics = [];
-
-    // Display host heatmaps if the stack definition has a host metrics service to display it.
-    if(App.get('services.hostMetrics').length) {
-      metrics.pushObjects([
-        App.MainChartHeatmapDiskSpaceUsedMetric.create(),
-        App.MainChartHeatmapMemoryUsedMetric.create(),
-        App.MainChartHeatmapCpuWaitIOMetric.create()
-      ]);
-    }
-
-    return metrics;
-  }.property(),
-
-  selectedMetric: null,
-
-  inputMaximum: '',
-
   validation: function () {
     if (this.get('selectedMetric')) {
       if (/^\d+$/.test(this.get('inputMaximum'))) {
@@ -140,7 +234,7 @@ App.MainChartsHeatmapController = Em.Controller.extend({
 
   addRackView: function (view) {
     this.get('rackViews').push(view);
-    if (this.get('rackViews').length == this.get('modelRacks').length) {
+    if (this.get('rackViews').length == this.get('racks').length) {
       this.displayAllRacks();
     }
   },
@@ -153,28 +247,17 @@ App.MainChartsHeatmapController = Em.Controller.extend({
   },
 
   showHeatMapMetric: function (event) {
-    var metricItem = event.context;
-    if (metricItem) {
-      this.set('selectedMetric', metricItem);
-    }
+    var self = this;
+    var metricItem = Em.Object.create(event.context);
+    this.saveWidgetLayout([metricItem]).done(function(){
+      self.loadActiveWidgetLayout();
+    });
   },
 
   hostToSlotMap: function () {
     return this.get('selectedMetric.hostToSlotMap');
   }.property('selectedMetric.hostToSlotMap'),
 
-  loadMetrics: function () {
-    var selectedMetric = this.get('selectedMetric');
-    var hostNames = [];
-    if (selectedMetric && this.get('racks').everyProperty('isLoaded', true)) {
-      this.get('racks').forEach(function (rack) {
-        hostNames = hostNames.concat(rack.hosts.mapProperty('hostName'));
-      });
-      selectedMetric.refreshHostSlots(hostNames);
-    }
-    this.set('inputMaximum', this.get('selectedMetric.maximumValue'));
-  }.observes('selectedMetric'),
-
   /**
    * return class name for to be used for containing each rack.
    *

+ 2 - 86
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric.js

@@ -32,7 +32,7 @@ var heatmap = require('utils/heatmap');
  * </ul>
  * 
  */
-App.MainChartHeatmapMetric = Em.Object.extend(heatmap.mappers, {
+App.MainChartHeatmapMetric = Em.Object.extend({
   /**
    * Name of this metric
    */
@@ -93,11 +93,6 @@ App.MainChartHeatmapMetric = Em.Object.extend(heatmap.mappers, {
    */
   units: '',
 
-  /**
-   * Indicates whether this metric is currently loading data from the server.
-   * {Boolean}
-   */
-  loading: false,
 
   /**
    * Provides following information about slots in an array of objects.
@@ -199,51 +194,6 @@ App.MainChartHeatmapMetric = Em.Object.extend(heatmap.mappers, {
    */
   slotDefinitionLabelSuffix: '',
 
-  defaultMetric: '',
-
-  /**
-   * Name in the <code>App.ajax</code>
-   * @type {String}
-   */
-  ajaxIndex: 'hosts.metrics',
-
-  /**
-   * Additional data for ajax-request
-   * May be redeclared in child-objects
-   * @type {Object}
-   */
-  ajaxData: {},
-
-  /**
-   * Maps server JSON into an object where keys are hostnames and values are the
-   * true metric values. This function by default will map 'defaultMetric' into
-   * its corresponding value.
-   * 
-   * @Function
-   */
-  metricMapper: function (json) {
-    var hostToValueMap = {};
-    var metricName = this.get('defaultMetric');
-    if (json.items) {
-      var props = metricName.split('.');
-      json.items.forEach(function (item) {
-        var value = item;
-        props.forEach(function (prop) {
-          if (value != null && prop in value) {
-            value = value[prop];
-          } else {
-            value = null;
-          }
-        });
-        if (value != null) {
-          var hostName = item.Hosts.host_name;
-          hostToValueMap[hostName] = value;
-        }
-      });
-    }
-    return hostToValueMap;
-  },
-
   hostToValueMap: null,
 
   hostToSlotMap: function () {
@@ -252,7 +202,7 @@ App.MainChartHeatmapMetric = Em.Object.extend(heatmap.mappers, {
     var hostToSlotMap = {};
     if (hostToValueMap && hostNames) {
       hostNames.forEach(function (hostName) {
-        var slot = this.calculateSlot(hostToValueMap, hostName)
+        var slot = this.calculateSlot(hostToValueMap, hostName);
         if (slot > -1) {
           hostToSlotMap[hostName] = slot;
         }
@@ -293,40 +243,6 @@ App.MainChartHeatmapMetric = Em.Object.extend(heatmap.mappers, {
     return slot;
   },
 
-  /**
-   * Determines which slot each host falls into. This information is given to
-   * the callback's #map(hostnameToSlotObject) method. The
-   * 'hostnameToSlotObject' has key as hostname, and the slot index as value.
-   */
-  refreshHostSlots: function (hostNames) {
-    this.set('loading', true);
-    this.set('hostNames', hostNames);
-    var fixedMetricName = this.get('defaultMetric');
-    fixedMetricName = fixedMetricName.replace(/\./g, "/");
-    var ajaxData = {
-      metricName: fixedMetricName
-    };
-    jQuery.extend(ajaxData, this.get('ajaxData'));
-
-    App.ajax.send({
-      name: this.get('ajaxIndex'),
-      sender: this,
-      data: ajaxData,
-      success: 'refreshHostSlotsSuccessCallback',
-      error: 'refreshHostSlotsErrorCallback'
-    });
-  },
-
-  refreshHostSlotsSuccessCallback: function (data) {
-    var hostToValueMap = this.metricMapper(data);
-    this.set('hostToValueMap', hostToValueMap);
-    this.set('loading', false);
-  },
-
-  refreshHostSlotsErrorCallback: function () {
-    this.set('loading', false);
-  },
-
   /**
    * Turns numbers into displayable values. For example 24.345432425 into 24.3
    * etc.

+ 0 - 39
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO.js

@@ -1,39 +0,0 @@
-/**
- * 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.MainChartHeatmapCpuWaitIOMetric = App.MainChartHeatmapMetric.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.cpuWaitIO'),
-  maximumValue: 100,
-  defaultMetric: 'metrics.cpu.cpu_wio',
-  units: '%',
-  slotDefinitionLabelSuffix: '%',
-  metricMapper: function (json) {
-    var map = this._super(json);
-    for ( var host in map) {
-      if (host in map) {
-        var val = map[host];
-        map[host] = (val * 100).toFixed(1);
-      }
-    }
-    return map;
-  }
-});

+ 0 - 45
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs.js

@@ -1,45 +0,0 @@
-/**
- * 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');
-
-/**
- * Base class for any HDFS metric.
- */
-App.MainChartHeatmapDFSMetrics = App.MainChartHeatmapMetric.extend({
-
-  ajaxIndex: 'hosts.metrics.host_component',
-
-  ajaxData: {
-    serviceName: 'HDFS',
-    componentName: 'DATANODE'
-  },
-
-  /**
-   * Custom mapper for DFS metrics
-   */
-  metricMapper: function(json) {
-    return this.metricMapperWithTransform(json, this.get('defaultMetric'), this.get('transformValue'));
-  },
-  /**
-   * Utility function which allows extending classes to transform the value
-   * assigned to a host.
-   * 
-   * @Function
-   */
-  transformValue: null
-});

+ 0 - 32
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread.js

@@ -1,32 +0,0 @@
-/**
- * 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.MainChartHeatmapDFSBytesReadMetric = App.MainChartHeatmapDFSMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.bytesRead'),
-  maximumValue: 1024, // 1GB
-  defaultMetric: 'metrics.dfs.datanode.bytes_read',
-  units: 'MB',
-  slotDefinitionLabelSuffix: 'MB',
-  transformValue: function (value) {
-    return value / (1024 * 1024); // bytes divided by 1MB.
-  }
-});

+ 0 - 32
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten.js

@@ -1,32 +0,0 @@
-/**
- * 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.MainChartHeatmapDFSBytesWrittenMetric = App.MainChartHeatmapDFSMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.bytesWritten'),
-  maximumValue: 1024, // 1GB
-  defaultMetric: 'metrics.dfs.datanode.bytes_written',
-  units: 'MB',
-  slotDefinitionLabelSuffix: 'MB',
-  transformValue: function (value) {
-    return value / (1024 * 1024); // bytes divided by 1MB.
-  }
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_gctime.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapDFSGCTimeMillisMetric = App.MainChartHeatmapDFSMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.DFSGarbageCollection'),
-  maximumValue: 10000,
-  defaultMetric: 'metrics.jvm.gcTimeMillis',
-  units: ' ms',
-  slotDefinitionLabelSuffix: ' ms'
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_memHeapUsed.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapDFSMemHeapUsedMetric = App.MainChartHeatmapDFSMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.DFSMemHeapUsed'),
-  maximumValue: 512,
-  defaultMetric: 'metrics.jvm.memHeapUsedM',
-  units: 'MB',
-  slotDefinitionLabelSuffix: 'MB'
-});

+ 0 - 65
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused.js

@@ -1,65 +0,0 @@
-/**
- * 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.MainChartHeatmapDiskSpaceUsedMetric = App.MainChartHeatmapMetric.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.diskSpaceUsed'),
-  maximumValue: 100,
-  defaultMetric: 'metrics.disk',
-  units: '%',
-  slotDefinitionLabelSuffix: '%',
-  metricMapper: function (json) {
-    var hostToValueMap = {};
-    var self = this;
-    var metricName = this.get('defaultMetric');
-    if (json.items) {
-      var props = metricName.split('.');
-      json.items.forEach(function (item) {
-        var value = item;
-        props.forEach(function (prop) {
-          if (value != null && prop in value) {
-            value = value[prop];
-          } else {
-            value = null;
-          }
-        });
-        if (value != null) {
-          value = self.diskUsageFormatted(value.disk_total - value.disk_free, value.disk_total);
-          var hostName = item.Hosts.host_name;
-          hostToValueMap[hostName] = value;
-        }
-      });
-    }
-    return hostToValueMap;
-  },
-
-  /**
-   * Format percent disk usage to float with 2 digits
-   */
-  diskUsageFormatted: function(diskUsed, diskTotal) {
-    var diskUsage = (diskUsed) / diskTotal * 100;
-    if (isNaN(diskUsage) || diskUsage < 0 || diskUsage > 100) {
-      return Em.I18n.t('charts.heatmap.unknown');
-    }
-    var s = Math.round(diskUsage * Math.pow(10, 2)) / Math.pow(10, 2);
-    return isNaN(s) ? 0 : s;
-  }
-});

+ 0 - 46
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase.js

@@ -1,46 +0,0 @@
-/**
- * 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');
-
-/**
- * Base class for any HDFS metric.
- */
-App.MainChartHeatmapHbaseMetrics = App.MainChartHeatmapMetric.extend({
-
-  ajaxIndex: 'hosts.metrics.host_component',
-
-  ajaxData: {
-    serviceName: 'HBASE',
-    componentName: 'HBASE_REGIONSERVER'
-  },
-
-  /**
-   * Custom mapper for HBase metrics
-   */
-  metricMapper: function(json) {
-    return this.metricMapperWithTransform(json, this.get('defaultMetric'), this.get('transformValue'));
-  },
-
-  /**
-   * Utility function which allows extending classes to transform the value
-   * assigned to a host.
-   *
-   * @Function
-   */
-  transformValue: null
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_compactionqueue.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapHbaseCompactionQueueSize = App.MainChartHeatmapHbaseMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.HbaseRegionServerCompactionQueueSize'),
-  maximumValue: 10,
-  defaultMetric: 'metrics.hbase.regionserver.compactionQueueSize',
-  units: '',
-  slotDefinitionLabelSuffix: ''
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_memstoresize.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapHbaseMemStoreSize = App.MainChartHeatmapHbaseMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.HbaseRegionServerMemStoreSize'),
-  maximumValue: 100*1024*1024,
-  defaultMetric: 'metrics.hbase.regionserver.memstoreSize',
-  units: 'B',
-  slotDefinitionLabelSuffix: 'B'
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_readrequest.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapHbaseReadReqCount = App.MainChartHeatmapHbaseMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.HbaseRegionServerReadCount'),
-  maximumValue: 200,
-  defaultMetric: 'metrics.hbase.regionserver.readRequestsCount',
-  units: '',
-  slotDefinitionLabelSuffix: ''
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_regions.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapHbaseRegions = App.MainChartHeatmapHbaseMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.HbaseRegionServerRegions'),
-  maximumValue: 10,
-  defaultMetric: 'metrics.hbase.regionserver.regions',
-  units: '',
-  slotDefinitionLabelSuffix: ''
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_writerequest.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapHbaseWriteReqCount = App.MainChartHeatmapHbaseMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.HbaseRegionServerWriteCount'),
-  maximumValue: 200,
-  defaultMetric: 'metrics.hbase.regionserver.writeRequestsCount',
-  units: '',
-  slotDefinitionLabelSuffix: ''
-});

+ 0 - 63
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused.js

@@ -1,63 +0,0 @@
-/**
- * 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');
-
-/**
- * Base class for any heatmap metric.
- * 
- * This class basically provides the following for each heatmap metric.
- * <ul>
- * <li> Provides number of slots in which temperature can fall.
- * <li> Maintains the maximum value so as to scale slot ranges.
- * <li> Gets JSON data from server and maps response for all hosts into above
- * slots.
- * </ul>
- * 
- */
-App.MainChartHeatmapMemoryUsedMetric = App.MainChartHeatmapMetric.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.memoryUsed'),
-  maximumValue: 100,
-  defaultMetric: 'metrics.memory',
-  units: '%',
-  slotDefinitionLabelSuffix: '%',
-  metricMapper: function (json) {
-    var hostToValueMap = {};
-    var metricName = this.get('defaultMetric');
-    if (json.items) {
-      var props = metricName.split('.');
-      json.items.forEach(function (item) {
-        var value = item;
-        props.forEach(function (prop) {
-          if (value != null && prop in value) {
-            value = value[prop];
-          } else {
-            value = null;
-          }
-        });
-        if (value != null) {
-          var total = value.mem_total;
-          var used = value.mem_total - value.mem_free - value.mem_cached;
-          value = ((used * 100) / total).toFixed(1);
-          var hostName = item.Hosts.host_name;
-          hostToValueMap[hostName] = value;
-        }
-      });
-    }
-    return hostToValueMap;
-  }
-});

+ 0 - 45
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_processrun.js

@@ -1,45 +0,0 @@
-/**
- * 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');
-
-/**
- * Base class for any heatmap metric.
- *
- * This class basically provides the following for each heatmap metric.
- * <ul>
- * <li> Provides number of slots in which temperature can fall.
- * <li> Maintains the maximum value so as to scale slot ranges.
- * <li> Gets JSON data from server and maps response for all hosts into above
- * slots.
- * </ul>
- *
- */
-App.MainChartHeatmapProcessRunMetric = App.MainChartHeatmapMetric.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.processRun'),
-  maximumValue: 1,
-  defaultMetric: 'metrics.process.proc_run',
-  units: 'Processes',
-  metricMapper: function (json) {
-    var map = this._super(json);
-    for (var host in map) {
-      var val = map[host];
-      map[host] = val.toFixed(1);
-    }
-    return map;
-  }
-});

+ 0 - 46
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn.js

@@ -1,46 +0,0 @@
-/**
- * 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');
-
-/**
- * Base class for any YARN metric.
- */
-App.MainChartHeatmapYarnMetrics = App.MainChartHeatmapMetric.extend({
-
-  ajaxIndex: 'hosts.metrics.host_component',
-
-  ajaxData: {
-    serviceName: 'YARN',
-    componentName: 'NODEMANAGER'
-  },
-
-  /**
-   * Custom mapper for YARN metrics
-   */
-  metricMapper: function(json) {
-    return this.metricMapperWithTransform(json, this.get('defaultMetric'), this.get('transformValue'));
-  },
-
-  /**
-   * Utility function which allows extending classes to transform the value
-   * assigned to a host.
-   *
-   * @Function
-   */
-  transformValue: null
-});

+ 0 - 66
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed.js

@@ -1,66 +0,0 @@
-/**
- * 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.MainChartHeatmapYarnResourceUsedMetric = App.MainChartHeatmapYarnMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.YarnMemoryUsed'),
-  maximumValue: 100,
-  defaultMetric: 'metrics.yarn',
-  units: ' %',
-  slotDefinitionLabelSuffix: ' %',
-
-  metricMapper: function (json) {
-    var hostToValueMap = {};
-    var self = this;
-    var metricName = this.get('defaultMetric');
-    if (json.host_components) {
-      var props = metricName.split('.');
-      json.host_components.forEach(function (host) {
-        var value = host;
-        props.forEach(function (prop) {
-          if (value != null && prop in value) {
-            value = value[prop];
-          } else {
-            value = null;
-          }
-        });
-        if (value != null) {
-          value = self.memoryUsageFormatted(value.AllocatedGB, value.AvailableGB + value.AllocatedGB);
-          var hostName = host.HostRoles.host_name;
-          hostToValueMap[hostName] = value;
-        }
-      });
-    }
-    return hostToValueMap;
-  },
-
-  /**
-   * Format percent YARN memory used to float with 2 digits
-   */
-  memoryUsageFormatted: function(used, total) {
-    var usage = (used) / total * 100;
-    if (isNaN(usage) || usage < 0 || usage > 100) {
-      return Em.I18n.t('charts.heatmap.unknown');
-    }
-    var s = usage.toFixed(1);
-    return isNaN(s) ? 0 : s;
-  }
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_gctime.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapYarnGCTimeMillisMetric = App.MainChartHeatmapYarnMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.YarnGCTime'),
-  maximumValue: 10000,
-  defaultMetric: 'metrics.jvm.gcTimeMillis',
-  units: ' ms',
-  slotDefinitionLabelSuffix: ' ms'
-});

+ 0 - 29
ambari-web/app/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_memHeapUsed.js

@@ -1,29 +0,0 @@
-/**
- * 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.MainChartHeatmapYarnMemHeapUsedMetric = App.MainChartHeatmapYarnMetrics.extend({
-  name: Em.I18n.t('charts.heatmap.metrics.YarnMemHeapUsed'),
-  maximumValue: 512,
-  defaultMetric: 'metrics.jvm.memHeapUsedM',
-  units: 'MB',
-  slotDefinitionLabelSuffix: 'MB'
-});

+ 1 - 32
ambari-web/app/controllers/main/service/info/heatmap.js

@@ -17,36 +17,5 @@
  */
 var App = require('app');
 App.MainServiceInfoHeatmapController = App.MainChartsHeatmapController.extend({
-  name: 'mainServiceInfoHeatmapController',
-  allMetrics: function () {
-    var metrics = [];
-    var serviceName = this.get('content.serviceName');
-    switch (serviceName) {
-      case 'HDFS':
-        metrics.pushObjects([
-          App.MainChartHeatmapDFSBytesReadMetric.create(),
-          App.MainChartHeatmapDFSBytesWrittenMetric.create(),
-          App.MainChartHeatmapDFSGCTimeMillisMetric.create(),
-          App.MainChartHeatmapDFSMemHeapUsedMetric.create()
-        ]);
-        break;
-      case 'YARN':
-        metrics.pushObjects([
-          App.MainChartHeatmapYarnGCTimeMillisMetric.create(),
-          App.MainChartHeatmapYarnMemHeapUsedMetric.create(),
-          App.MainChartHeatmapYarnResourceUsedMetric.create()
-        ]);
-        break;
-      case 'HBASE':
-        metrics.pushObjects([
-          App.MainChartHeatmapHbaseReadReqCount.create(),
-          App.MainChartHeatmapHbaseWriteReqCount.create(),
-          App.MainChartHeatmapHbaseCompactionQueueSize.create(),
-          App.MainChartHeatmapHbaseRegions.create(),
-          App.MainChartHeatmapHbaseMemStoreSize.create()
-        ]);
-        break;
-    }
-    return metrics;
-  }.property('content.serviceName')
+  name: 'mainServiceInfoHeatmapController'
 });

+ 4 - 111
ambari-web/app/controllers/main/service/info/summary.js

@@ -17,7 +17,7 @@
 
 var App = require('app');
 
-App.MainServiceInfoSummaryController = Em.Controller.extend({
+App.MainServiceInfoSummaryController = Em.Controller.extend(App.WidgetSectionMixin, {
   name: 'mainServiceInfoSummaryController',
 
   selectedFlumeAgent: null,
@@ -40,29 +40,9 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
    */
   isPreviousRangerConfigsCallFailed: false,
 
-  /**
-   * UI section name
-   */
-  sectionName: function () {
-    return this.get('content.serviceName') + "_SUMMARY";
-  }.property('content.serviceName'),
-
-  /**
-   * UI default layout name
-   */
-  defaultLayoutName: function () {
-    return "default_" + this.get('content.serviceName').toLowerCase() + "_dashboard";
-  }.property('content.serviceName'),
+  layoutNameSuffix: "_dashboard",
 
-  /**
-   * Does Service has widget descriptor defined in the stack
-   * @type {boolean}
-   */
-  isServiceWithEnhancedWidgets: function () {
-    var serviceName = this.get('content.serviceName');
-    var stackService = App.StackService.find().findProperty('serviceName', serviceName);
-    return stackService.get('isServiceWithWidgets') && App.supports.customizedWidgets;
-  }.property('content.serviceName'),
+  sectionNameSuffix: "_SUMMARY",
 
   /**
    * Ranger plugins data
@@ -317,10 +297,6 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
     });
   },
 
-  /**
-   * @type {boolean}
-   */
-  isWidgetsLoaded: false,
 
   /**
    * @type {boolean}
@@ -337,24 +313,6 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
    */
   isMineWidgetsLoaded: false,
 
-  /**
-   *  @Type {App.WidgetLayout}
-   */
-  activeWidgetLayout: {},
-
-
-  /**
-   * @type {Em.A}
-   */
-  widgets: function () {
-    if (this.get('isWidgetsLoaded')) {
-      if (this.get('activeWidgetLayout.widgets')) {
-        return this.get('activeWidgetLayout.widgets').toArray();
-      } else {
-        return  [];
-      }
-    }
-  }.property('isWidgetsLoaded'),
 
   /**
    * @type {Em.A}
@@ -384,41 +342,6 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
     this.set('isWidgetLayoutsLoaded', true);
   },
 
-  /**
-   * load widgets defined by user
-   * @returns {$.ajax}
-   */
-  loadActiveWidgetLayout: function () {
-    this.set('activeWidgetLayout', {});
-    this.set('isWidgetsLoaded', false);
-    if (this.get('isServiceWithEnhancedWidgets')) {
-      return App.ajax.send({
-        name: 'widget.layout.get',
-        sender: this,
-        data: {
-          layoutName: this.get('defaultLayoutName'),
-          serviceName: this.get('content.serviceName')
-        },
-        success: 'loadActiveWidgetLayoutSuccessCallback'
-      });
-    } else {
-      this.set('isWidgetsLoaded', true);
-    }
-  },
-
-
-  /**
-   * success callback of <code>loadWidgets()</code>
-   * @param {object|null} data
-   */
-  loadActiveWidgetLayoutSuccessCallback: function (data) {
-    if (data.items[0]) {
-      App.widgetMapper.map(data.items[0].WidgetLayoutInfo);
-      App.widgetLayoutMapper.map(data);
-      this.set('activeWidgetLayout', App.WidgetLayout.find().findProperty('layoutName', this.get('defaultLayoutName')));
-      this.set('isWidgetsLoaded', true);
-    }
-  },
 
   /**
    * load all shared widgets to show on widget browser
@@ -525,7 +448,7 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
     });
     widgetIds.pushObject({
       "id": widgetToAdd.id
-    })
+    });
     var data = {
       "WidgetLayoutInfo": {
         "display_name": activeLayout.get("displayName"),
@@ -644,36 +567,6 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
 
   },
 
-  /**
-   * save layout after re-order widgets
-   * return {$.ajax}
-   */
-  saveReorderedLayout: function (widgets) {
-    var activeLayout = this.get('activeWidgetLayout');
-    var data = {
-      "WidgetLayoutInfo": {
-        "display_name": activeLayout.get("displayName"),
-        "id": activeLayout.get("id"),
-        "layout_name": activeLayout.get("layoutName"),
-        "scope": activeLayout.get("scope"),
-        "section_name": activeLayout.get("sectionName"),
-        "widgets": widgets.map(function (widget) {
-          return {
-            "id": widget.get('id')
-          }
-        })
-      }
-    };
-    return App.ajax.send({
-      name: 'widget.layout.edit',
-      sender: this,
-      data: {
-        layoutId: activeLayout.get("id"),
-        data: data
-      }
-    });
-  },
-
   /**
    * create widget
    */

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

@@ -2227,23 +2227,6 @@ Em.I18n.translations = {
   'charts.heatmap.unknown': 'Unknown',
   'charts.heatmap.label.notApplicable' :'Not Applicable',
   'charts.heatmap.label.invalidData' :'Invalid data',
-  'charts.heatmap.metrics.bytesRead' :'HDFS Bytes Read',
-  'charts.heatmap.metrics.bytesWritten' :'HDFS Bytes Written',
-  'charts.heatmap.metrics.DFSGarbageCollection' :'HDFS Garbage Collection Time',
-  'charts.heatmap.metrics.DFSMemHeapUsed' :'HDFS JVM Heap Memory Used',
-  'charts.heatmap.metrics.diskSpaceUsed' :'Host Disk Space Used %',
-  'charts.heatmap.metrics.YarnGCTime' :'YARN Garbage Collection Time',
-  'charts.heatmap.metrics.YarnMemHeapUsed' :'YARN JVM Heap Memory Used',
-
-  'charts.heatmap.metrics.memoryUsed' :'Host Memory Used %',
-  'charts.heatmap.metrics.processRun' :'Total Running Processes',
-  'charts.heatmap.metrics.YarnMemoryUsed' :'YARN Memory used %',
-  'charts.heatmap.metrics.cpuWaitIO':'Host CPU Wait I/O %',
-  'charts.heatmap.metrics.HbaseRegionServerReadCount': 'HBase Read Request Count',
-  'charts.heatmap.metrics.HbaseRegionServerWriteCount': 'HBase Write Request Count',
-  'charts.heatmap.metrics.HbaseRegionServerCompactionQueueSize': 'HBase Compaction Queue Size',
-  'charts.heatmap.metrics.HbaseRegionServerRegions': 'HBase Regions',
-  'charts.heatmap.metrics.HbaseRegionServerMemStoreSize': 'HBase Memstore Sizes',
   'metric.notFound':'no items found',
   'metric.default':'combined',
   'metric.cpu':'cpu',

+ 2 - 1
ambari-web/app/mixins.js

@@ -45,6 +45,7 @@ require('mixins/wizard/wizard_menu_view');
 require('mixins/wizard/assign_master_components');
 require('mixins/common/configs/enhanced_configs');
 require('mixins/common/configs/configs_saver');
-require('mixins/common/widget_mixin');
+require('mixins/common/widgets/widget_mixin');
+require('mixins/common/widgets/widget_section');
 require('mixins/unit_convert/base_unit_convert_mixin');
 require('mixins/unit_convert/convert_unit_widget_view_mixin');

+ 90 - 10
ambari-web/app/mixins/common/widget_mixin.js → ambari-web/app/mixins/common/widgets/widget_mixin.js

@@ -56,6 +56,7 @@ App.WidgetMixin = Ember.Mixin.create({
   content: null,
 
   beforeRender: function () {
+    this.get('metrics').clear();
     this.loadMetrics();
   },
 
@@ -72,7 +73,19 @@ App.WidgetMixin = Ember.Mixin.create({
     for (var i in requestData) {
       request = requestData[i];
       requestCounter++;
-      if (request.host_component_criteria) {
+      if (this.get('content.widgetType') === 'HEATMAP'){
+        if (request.service_name === 'STACK') {
+          this.getHostsMetrics(request).complete(function () {
+            requestCounter--;
+            if (requestCounter === 0) self.onMetricsLoaded();
+          });
+        } else {
+          this.getHostComponentsMetrics(request).complete(function () {
+            requestCounter--;
+            if (requestCounter === 0) self.onMetricsLoaded();
+          });
+        }
+      } else if (request.host_component_criteria) {
         this.getHostComponentMetrics(request).always(function () {
           requestCounter--;
           if (requestCounter === 0) self.onMetricsLoaded();
@@ -153,7 +166,7 @@ App.WidgetMixin = Ember.Mixin.create({
   },
 
   /**
-   * make GET call to server in order to fetch service-component metrics
+   * make GET call to server in order to fetch specifc host-component metrics
    * @param {object} request
    * @returns {$.Deferred}
    */
@@ -185,6 +198,8 @@ App.WidgetMixin = Ember.Mixin.create({
     return dfd.promise();
   },
 
+
+
   /**
    * make GET call to server in order to fetch host-component names
    * @param {object} request
@@ -203,6 +218,7 @@ App.WidgetMixin = Ember.Mixin.create({
     });
   },
 
+
   /**
    * callback on getting aggregated metrics and host component metrics
    * @param data
@@ -218,6 +234,66 @@ App.WidgetMixin = Ember.Mixin.create({
     }, this);
   },
 
+  /**
+   * make GET call to get host component metrics accross
+   * @param {object} request
+   * @return {$.ajax}
+   */
+  getHostComponentsMetrics: function(request) {
+    request.metric_paths.forEach(function(_metric,index){
+      request.metric_paths[index] = "host_components/" + _metric;
+    });
+    return App.ajax.send({
+      name: 'widgets.serviceComponent.metrics.get',
+      sender: this,
+      data: {
+        serviceName: request.service_name,
+        componentName: request.component_name,
+        metricPaths: request.metric_paths.join(',')
+      },
+      success: 'getHostComponentsMetricsSuccessCallback'
+    });
+  },
+
+
+  getHostComponentsMetricsSuccessCallback: function(data) {
+    var metrics = this.get('content.metrics');
+    data.host_components.forEach(function(item){
+      metrics.forEach(function (_metric) {
+        if (!Em.isNone(Em.get(item, _metric.metric_path.replace(/\//g, '.')))) {
+          var metric = $.extend({},_metric,true);
+          metric.data =  Em.get(item, _metric.metric_path.replace(/\//g, '.'));
+          metric.hostName = item.HostRoles.host_name;
+          this.get('metrics').pushObject(metric);
+        }
+      }, this);
+    },this);
+  },
+
+  getHostsMetrics: function(request) {
+    return App.ajax.send({
+      name: 'widgets.hosts.metrics.get',
+      sender: this,
+      data: {
+        metricPaths: request.metric_paths.join(',')
+      },
+      success: 'getHostsMetricsSuccessCallback'
+    });
+  },
+
+  getHostsMetricsSuccessCallback: function(data) {
+    var metrics = this.get('content.metrics');
+    data.items.forEach(function(item){
+      metrics.forEach(function (_metric,index) {
+        if (!Em.isNone(Em.get(item, _metric.metric_path.replace(/\//g, '.')))) {
+          var metric = $.extend({},_metric,true);
+          metric.data =  Em.get(item, _metric.metric_path.replace(/\//g, '.'));
+          metric.hostName = item.Hosts.host_name;
+          this.get('metrics').pushObject(metric);
+        }
+      }, this);
+    },this);
+  },
 
   /**
    * callback on metrics loaded
@@ -294,18 +370,22 @@ App.WidgetMixin = Ember.Mixin.create({
 
       //replace values with metrics data
       var beforeCompute = _expression.replace(this.get('VALUE_NAME_REGEX'), function (match) {
-        if (metrics.someProperty('name', match)) {
-          return metrics.findProperty('name', match).data;
+        if (window.isNaN(match)) {
+          if (metrics.someProperty('name', match)) {
+            return metrics.findProperty('name', match).data;
+          } else {
+            validExpression = false;
+            console.error('Metrics with name "' + match + '" not found to compute expression');
+          }
         } else {
-          validExpression = false;
-          console.warn('Metrics not found to compute expression');
+          return match;
         }
       });
 
-      if (validExpression) {
-        //check for correct math expression
-        validExpression = this.get('MATH_EXPRESSION_REGEX').test(beforeCompute);
-        !validExpression && console.warn('Value is not correct mathematical expression');
+      //check for correct math expression
+      if (!(validExpression && this.get('MATH_EXPRESSION_REGEX').test(beforeCompute))) {
+        validExpression = false;
+        console.error('Value for metric is not correct mathematical expression: ' + beforeCompute);
       }
 
       result['${' + _expression + '}'] = (validExpression) ? Number(window.eval(beforeCompute)).toString() : value;

+ 146 - 0
ambari-web/app/mixins/common/widgets/widget_section.js

@@ -0,0 +1,146 @@
+/**
+ * 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.WidgetSectionMixin = Ember.Mixin.create({
+  /**
+   * UI default layout name
+   */
+  defaultLayoutName: function () {
+    var heatmapType;
+    if (this.get('content.serviceName')) {
+      heatmapType = this.get('content.serviceName').toLowerCase();
+    } else {
+      heatmapType = "system";
+    }
+    return "default_" + heatmapType + this.layoutNameSuffix;
+  }.property('content.serviceName'),
+
+  /**
+   * UI section name
+   */
+  sectionName: function () {
+    if (this.get('content.serviceName')) {
+      return this.get('content.serviceName') + this.sectionNameSuffix;
+    } else {
+      return "SYSTEM"  + this.sectionNameSuffix
+    }
+  }.property('content.serviceName'),
+
+
+
+  /**
+   * Does Service has widget descriptor defined in the stack
+   * @type {boolean}
+   */
+  isServiceWithEnhancedWidgets: function () {
+    var isServiceWithWidgetdescriptor;
+    var serviceName = this.get('content.serviceName');
+    if (serviceName) {
+      isServiceWithWidgetdescriptor = App.StackService.find().findProperty('serviceName', serviceName).get('isServiceWithWidgets');
+    } else if (this.get('sectionName') === 'SYSTEM_HEATMAPS') {
+      isServiceWithWidgetdescriptor = true;
+    }
+    return isServiceWithWidgetdescriptor && App.supports.customizedWidgets;
+  }.property('content.serviceName'),
+
+  /**
+   *  @Type {App.WidgetLayout}
+   */
+  activeWidgetLayout: {},
+
+  /**
+   * @type {Em.A}
+   */
+  widgets: function () {
+    if (this.get('isWidgetsLoaded')) {
+      if (this.get('activeWidgetLayout.widgets')) {
+        return this.get('activeWidgetLayout.widgets').toArray();
+      } else {
+        return  [];
+      }
+    }
+  }.property('isWidgetsLoaded'),
+
+  /**
+   * load widgets defined by user
+   * @returns {$.ajax}
+   */
+  loadActiveWidgetLayout: function () {
+    this.set('activeWidgetLayout', {});
+    this.set('isWidgetsLoaded', false);
+    if (this.get('isServiceWithEnhancedWidgets')) {
+      return App.ajax.send({
+        name: 'widget.layout.get',
+        sender: this,
+        data: {
+          layoutName: this.get('defaultLayoutName'),
+          serviceName: this.get('content.serviceName')
+        },
+        success: 'loadActiveWidgetLayoutSuccessCallback'
+      });
+    } else {
+      this.set('isWidgetsLoaded', true);
+    }
+  },
+
+
+  /**
+   * success callback of <code>loadActiveWidgetLayout()</code>
+   * @param {object|null} data
+   */
+  loadActiveWidgetLayoutSuccessCallback: function (data) {
+    if (data.items[0]) {
+      App.widgetMapper.map(data.items[0].WidgetLayoutInfo);
+      App.widgetLayoutMapper.map(data);
+      this.set('activeWidgetLayout', App.WidgetLayout.find().findProperty('layoutName', this.get('defaultLayoutName')));
+      this.set('isWidgetsLoaded', true);
+    }
+  },
+
+  /**
+   * save layout after re-order widgets
+   * return {$.ajax}
+   */
+  saveWidgetLayout: function (widgets) {
+    var activeLayout = this.get('activeWidgetLayout');
+    var data = {
+      "WidgetLayoutInfo": {
+        "display_name": activeLayout.get("displayName"),
+        "id": activeLayout.get("id"),
+        "layout_name": activeLayout.get("layoutName"),
+        "scope": activeLayout.get("scope"),
+        "section_name": activeLayout.get("sectionName"),
+        "widgets": widgets.map(function (widget) {
+          return {
+            "id": widget.get('id')
+          }
+        })
+      }
+    };
+    return App.ajax.send({
+      name: 'widget.layout.edit',
+      sender: this,
+      data: {
+        layoutId: activeLayout.get("id"),
+        data: data
+      }
+    });
+  }
+});

+ 2 - 0
ambari-web/app/models/widget.js

@@ -64,6 +64,8 @@ App.Widget = DS.Model.extend({
         return App.NumberWidgetView;
       case 'GAUGE':
         return App.GaugeWidgetView;
+      case 'HEATMAP':
+        return App.HeatmapWidgetView;
       default:
         return Em.View;
     }

+ 8 - 4
ambari-web/app/routes/main.js

@@ -142,8 +142,10 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
         route: '/heatmap',
         connectOutlets: function (router, context) {
           router.get('mainController').dataLoading().done(function () {
-            router.get('mainChartsHeatmapController').loadRacks();
-            router.get('mainChartsController').connectOutlet('mainChartsHeatmap');
+            router.get('mainChartsHeatmapController').loadRacks().done(function(data){
+              router.get('mainChartsHeatmapController').loadRacksSuccessCallback(data);
+              router.get('mainChartsController').connectOutlet('mainChartsHeatmap');
+            });
           });
         }
       }),
@@ -685,8 +687,10 @@ module.exports = Em.Route.extend(App.RouterRedirections, {
           var item = router.get('mainServiceItemController.content');
           if (item.get('isLoaded')) {
             router.get('mainController').dataLoading().done(function () {
-              router.get('mainServiceInfoHeatmapController').loadRacks();
-              router.get('mainServiceItemController').connectOutlet('mainServiceInfoHeatmap', item);
+              router.get('mainServiceInfoHeatmapController').loadRacks().done(function(data) {
+                router.get('mainServiceInfoHeatmapController').loadRacksSuccessCallback(data);
+                router.get('mainServiceItemController').connectOutlet('mainServiceInfoHeatmap', item);
+              });
             });
           }
         }

+ 39 - 0
ambari-web/app/templates/common/widget/heatmap_widget.hbs

@@ -0,0 +1,39 @@
+{{!
+* 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.
+}}
+
+<div class="heatmap-widget">
+  <div class="span10 heatmap-content">
+    <h4 id="heatmap-metric-loading">
+	        <span id="heatmap-metric-title">
+						{{view.content.displayName}} &nbsp;
+            {{#unless view.isLoaded}}
+              <i class='icon-spinner icon-spin icon-small'></i>
+            {{/unless}}
+					</span>
+    </h4>
+
+    <div class="row-fluid">
+      {{#each rack in view.racks}}
+        <div {{bindAttr class="controller.rackClass"}}>
+          {{view App.MainChartsHeatmapRackView rackBinding="rack" }}
+        </div>
+      {{/each}}
+    </div>
+    {{view App.MainChartsHeatmapHostDetailView}}
+  </div>
+</div>

+ 27 - 51
ambari-web/app/templates/main/charts/heatmap.hbs

@@ -19,59 +19,35 @@
 <div class="heatmap">
 
   <div class="container-fluid">
-	  <div class="row-fluid">
-	    <div class="span2 legend-column">
-		     <div class="btn-group" id="select-metric-btn-group">
-				  <button class="btn heatmap-select-metric-btn">{{t charts.heatmap.selectMetric}}</button>
-				  <button class="btn dropdown-toggle heatmap-toggle-metrics-btn" data-toggle="dropdown">
-				    <span class="caret"></span>
-				  </button>
-				  <ul class="dropdown-menu">
-				    {{#each metric in controller.allMetrics}}
-							<li class="heatmap-metrics-dropdown-links">
-                <a tabindex="-1" {{action showHeatMapMetric metric target="controller"}}>{{metric.name}}</a>
-							</li>
-            {{/each}}
-				  </ul>
-				</div>
+    <div class="row-fluid">
+      <div class="span2 legend-column">
+
+        {{view view.dropdownView}}
+
         {{#if controller.selectedMetric}}
-					<table class="legend">
-					  {{#each slot in controller.selectedMetric.slotDefinitions}}
-					    <tr>
-					      <td>
-					        <div class="tile" {{bindAttr style="slot.cssStyle"}}></div>
-					      </td>
-					      <td>{{slot.label}}</td>
-					    </tr>
-					  {{/each}}
-					</table>
-	        {{t common.maximum}}:
-	        <div id="inputMaximum" class="control-group">
-	          {{view Ember.TextField type="text" maxlength="8" valueBinding="controller.inputMaximum" class="span6"}}
-	          {{controller.selectedMetric.units}}
-	        </div>
+          <table class="legend">
+            {{#each slot in controller.selectedMetric.slotDefinitions}}
+              <tr>
+                <td>
+                  <div class="tile" {{bindAttr style="slot.cssStyle"}}></div>
+                </td>
+                <td>{{slot.label}}</td>
+              </tr>
+            {{/each}}
+          </table>
+          {{t common.maximum}}:
+          <div id="inputMaximum" class="control-group">
+            {{view Ember.TextField type="text" maxlength="8" valueBinding="controller.inputMaximum" class="span6"}}
+            {{controller.selectedMetric.units}}
+          </div>
         {{/if}}
-	    </div>
-	    <div class="span10 heatmap-content">
-	      <h4 id="heatmap-metric-loading">
-	        <span id="heatmap-metric-title">
-						{{controller.selectedMetric.name}} &nbsp;
-						{{#if controller.selectedMetric.loading}}
-              <i class='icon-spinner icon-spin icon-small'></i>
-						{{/if}}
-					</span>
-	      </h4>
-	      <div class="row-fluid">
-
-				  {{#each rack in controller.racks}}
-				    <div {{bindAttr class="controller.rackClass"}}>
-				      {{view App.MainChartsHeatmapRackView rackBinding="rack" }}
-				    </div>
-				  {{/each}}
-			  </div>
-			  {{view App.MainChartsHeatmapHostDetailView}}
-	    </div>
-	  </div>
+      </div>
+      {{#if controller.activeWidget}}
+        <div class="active-widget" {{bindAttr id="activeWidget.id"}}>
+          {{view activeWidget.viewClass contentBinding="activeWidget" racksBinding = "racks" idBinding="activeWidget.id"}}
+        </div>
+      {{/if}}
+    </div>
   </div>
 
 </div>

+ 38 - 0
ambari-web/app/templates/main/charts/heatmap_dropdown.hbs

@@ -0,0 +1,38 @@
+{{!
+* 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.
+}}
+
+<div class="btn-group">
+  <button class="btn heatmap-select-metric-btn">{{t charts.heatmap.selectMetric}}</button>
+  <button class="btn dropdown-toggle heatmap-toggle-metrics-btn" data-toggle="dropdown">
+    <span class="caret"></span>
+  </button>
+  <ul class="dropdown-menu">
+    {{#each category in controller.heatmapCategories}}
+      <li class="dropdown-submenu">
+        <a tabindex="-1" >{{category.displayName}}</a>
+        <ul class="dropdown-menu">
+          {{#each heatmap in category.heatmaps}}
+            <li>
+              <a tabindex="-1" {{action showHeatMapMetric heatmap target="controller"}}>{{heatmap.display_name}}</a>
+            </li>
+          {{/each}}
+        </ul>
+      </li>
+    {{/each}}
+  </ul>
+</div>

+ 32 - 0
ambari-web/app/templates/main/service/info/heatmap_dropdown.hbs

@@ -0,0 +1,32 @@
+{{!
+* 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.
+}}
+
+<div class="btn-group" id="select-metric-btn-group">
+  <button class="btn heatmap-select-metric-btn">{{t charts.heatmap.selectMetric}}</button>
+  <button class="btn dropdown-toggle heatmap-toggle-metrics-btn" data-toggle="dropdown">
+    <span class="caret"></span>
+  </button>
+
+  <ul class="dropdown-menu">
+    {{#each heatmap in controller.allHeatmaps}}
+      <li class="heatmap-metrics-dropdown-links">
+        <a tabindex="-1" {{action showHeatMapMetric heatmap target="controller"}}>{{heatmap.display_name}}</a>
+      </li>
+    {{/each}}
+  </ul>
+</div>

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

@@ -2406,6 +2406,11 @@ var urls = {
     }
   },
 
+  'widgets.get': {
+    real: '/clusters/{clusterName}/widgets?{urlParams}',
+    mock: '/data/widget_layouts/all_heatmaps.json'
+  },
+
   'widgets.all.shared.get': {
     real: '/clusters/{clusterName}/widgets?WidgetInfo/scope=CLUSTER&fields=*',
     mock: '/data/widget_layouts/all_shared_widgets.json'
@@ -2472,6 +2477,11 @@ var urls = {
     mock: '/data/metrics/{serviceName}/Append_num_ops.json'
   },
 
+  'widgets.hosts.metrics.get': {
+    real: '/clusters/{clusterName}/hosts?fields={metricPaths}',
+    mock: '/data/metrics/{serviceName}/Append_num_ops.json'
+  },
+
   'widgets.wizard.metrics.get': {
     real: '{stackVersionURL}/services?artifacts/Artifacts/artifact_name=metrics_descriptor&StackServices/service_name.in({serviceNames})&fields=artifacts/*',
     mock: '/data/metrics/HBASE/definition.json'

+ 1 - 1
ambari-web/app/utils/heatmap.js

@@ -39,7 +39,7 @@ module.exports = {
               value = transformValueFunction(value);
             }
             var hostName = hc.HostRoles.host_name;
-            hostToValueMap[hostName] = value;
+            hostToValueMap[hostName] = value.toFixed(1);
           }
         });
       }

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

@@ -76,6 +76,7 @@ require('views/common/widget/graph_widget_view');
 require('views/common/widget/template_widget_view');
 require('views/common/widget/gauge_widget_view');
 require('views/common/widget/number_widget_view');
+require('views/common/widget/heatmap_widget_view');
 require('views/common/assign_master_components_view');
 require('views/login');
 require('views/main');

+ 116 - 0
ambari-web/app/views/common/widget/heatmap_widget_view.js

@@ -0,0 +1,116 @@
+/**
+ * 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.HeatmapWidgetView = Em.View.extend(App.WidgetMixin, {
+  templateName: require('templates/common/widget/heatmap_widget'),
+
+  /**
+   * common metrics container
+   * @type {Array}
+   */
+  metrics: [],
+
+  /**
+   *  racks container  binded in the template
+   *  @type {Array}
+   */
+  racks: [],
+
+  /**
+   * draw widget
+   */
+  drawWidget: function () {
+    if (this.get('isLoaded')) {
+      var hostToValueMap = this.calculateValues();
+      var hostNames = [];
+      if (this.get('racks').everyProperty('isLoaded', true)) {
+        this.get('racks').forEach(function (rack) {
+          hostNames = hostNames.concat(rack.hosts.mapProperty('hostName'));
+        });
+      }
+
+      var metricObject = App.MainChartHeatmapMetric.create({
+        name: this.get('content.displayName'),
+        units: this.get('content.properties.display_unit'),
+        maximumValue: this.get('content.properties.max_limit'),
+        hostNames: hostNames,
+        hostToValueMap: hostToValueMap
+      });
+
+      this.set('controller.selectedMetric', metricObject);
+
+      this.set('controller.inputMaximum', metricObject.get('maximumValue'));
+    }
+  },
+
+  /**
+   * calculate value for heatmap widgets
+   */
+  calculateValues: function () {
+    var metrics = this.get('metrics');
+    var hostToValueMap = this.computeExpression(this.extractExpressions(this.get('content.values')[0]), metrics);
+    return hostToValueMap;
+  },
+
+
+  /**
+   * compute expression
+   * @param expressions
+   * @param metrics
+   * @returns {object}
+   */
+  computeExpression: function (expressions, metrics) {
+    var hostToValueMap = {};
+    var hostNames = metrics.mapProperty('hostName');
+    hostNames.forEach(function (_hostName) {
+      expressions.forEach(function (_expression) {
+        var validExpression = true;
+
+        //replace values with metrics data
+        var beforeCompute = _expression.replace(this.get('VALUE_NAME_REGEX'), function (match) {
+          var _metric;
+          if (window.isNaN(match)) {
+            _metric = metrics.filterProperty('name', match).findProperty('hostName', _hostName);
+            if (_metric) {
+              return _metric.data;
+            } else {
+              validExpression = false;
+              console.error('Metrics with name "' + match + '" not found to compute expression');
+            }
+          } else {
+            return match;
+          }
+        });
+
+        if (validExpression && this.get('MATH_EXPRESSION_REGEX').test(beforeCompute)) {
+          var value = Number(window.eval(beforeCompute)).toString();
+          if (value == "NaN")  {
+            value = 0
+          }
+          hostToValueMap[_hostName] = value;
+        } else {
+          console.error('Value for metric is not correct mathematical expression: ' + beforeCompute);
+        }
+      }, this);
+    }, this);
+
+    return hostToValueMap;
+  }
+});

+ 5 - 2
ambari-web/app/views/main/charts/heatmap.js

@@ -22,7 +22,10 @@ App.MainChartsHeatmapView = Em.View.extend({
   didInsertElement: function () {
     this._super();
     // set default metric
-    this.set('controller.selectedMetric', this.get('controller.allMetrics')[0]);
+    this.get('controller').loadPageData();
     $("#heatmapDetailsBlock").hide();
-  }
+  },
+  dropdownView: Em.View.extend({
+    templateName: require('templates/main/charts/heatmap_dropdown')
+  })
 });

+ 5 - 0
ambari-web/app/views/main/charts/heatmap/heatmap_host.js

@@ -21,6 +21,11 @@ var App = require('app');
 
 App.MainChartsHeatmapHostView = Em.View.extend({
   templateName: require('templates/main/charts/heatmap/heatmap_host'),
+
+  didInsertElement: function() {
+    $("#heatmapDetailsBlock").hide();
+  },
+
   /** @private */
   hostClass: 'hostBlock',
 

+ 1 - 90
ambari-web/app/views/main/charts/heatmap/heatmap_rack.js

@@ -29,31 +29,12 @@ App.MainChartsHeatmapRackView = Em.View.extend({
   /** loaded hosts of rack */
   hosts: [],
 
-  willDestroyElement: function () {
-    this.get('hosts').clear();
-  },
-
-  /**
-   * get hosts from the root controller
-   */
-  getHosts: function () {
-    var controller = this.get('controller');
-    var rackId = this.get('rack.rackId');
-    var rackMap = controller.get('rackMap');
-    this.pushHostsToRack(rackMap[rackId].hosts);
-  },
-
-  getHostsSuccessCallback: function (data, opt, params) {
-    this.pushHostsToRack(data);
-    this.displayHosts();
-  },
-
   /**
    * display hosts of rack
    */
   displayHosts: function () {
     var rackHosts = this.get('rack.hosts');
-    var rackCount = this.get('controller.modelRacks.length');
+    var rackCount = this.get('controller.racks.length');
 
     if (this.get('hosts.length') === 0) {
       if (rackHosts.length > 100 && rackCount == 1) {
@@ -72,77 +53,7 @@ App.MainChartsHeatmapRackView = Em.View.extend({
     }
   },
 
-  getHostsErrorCallback: function (request, ajaxOptions, error, opt, params) {
-    this.set('rack.isLoaded', true);
-  },
-  /**
-   * push hosts to rack
-   * @param data
-   */
-  pushHostsToRack: function (hosts) {
-    var newHostsData = hosts;
-    var rackHosts = this.get('rack.hosts');
-
-    if (rackHosts.length > 0) {
-      this.updateLoadedHosts(rackHosts, newHostsData);
-    } else {
-      this.set('rack.hosts', newHostsData);
-    }
-  },
-
-  updateLoadedHosts: function (rackHosts, newHostsData) {
-    var rackHostsMap = {};
-    var isNewHosts = false;
-
-    //create map
-    rackHosts.forEach(function (host) {
-      rackHostsMap[host.hostName] = host;
-    });
-
-    newHostsData.forEach(function (item) {
-      var currentHostInfo = rackHostsMap[item.hostName];
-
-      if (currentHostInfo) {
-        ['diskTotal', 'diskFree', 'cpuSystem', 'cpuUser', 'memTotal', 'memFree', 'hostComponents'].forEach(function (property) {
-          currentHostInfo[property] = item[property];
-        });
-        delete rackHostsMap[item.hostName];
-      } else {
-        isNewHosts = true;
-      }
-    }, this);
-
-    //if hosts were deleted or added then reload hosts view
-    if (!App.isEmptyObject(rackHostsMap) || isNewHosts) {
-      this.redrawHostsView(newHostsData)
-    }
-  },
-
-  /**
-   * reload hosts rack
-   * @param newHostsData
-   */
-  redrawHostsView: function (newHostsData) {
-    this.set('rack.isLoaded', false);
-    this.get('hosts').clear();
-    this.set('rack.hosts', newHostsData);
-  },
-
-  /**
-   * call metrics update after hosts of rack are loaded
-   */
-  updateMetrics: function(){
-    if (this.get('rack.isLoaded')) {
-      this.get('controller').loadMetrics();
-    }
-  }.observes('rack.isLoaded'),
-
   didInsertElement: function () {
-    this.set('rack.isLoaded', false);
-    if (this.get('rack.hosts.length') > 0) {
-      this.displayHosts();
-    }
-    this.getHosts();
     this.get('controller').addRackView(this);
   },
   /**

+ 3 - 1
ambari-web/app/views/main/service/info/heatmap_view.js

@@ -17,5 +17,7 @@
  */
 var App = require('app');
 App.MainServiceInfoHeatmapView = App.MainChartsHeatmapView.extend({
-  templateName: require('templates/main/charts/heatmap')
+  dropdownView: Em.View.extend({
+    templateName: require('templates/main/service/info/heatmap_dropdown')
+  })
 });

+ 1 - 1
ambari-web/app/views/main/service/info/summary.js

@@ -598,7 +598,7 @@ App.MainServiceInfoSummaryView = Em.View.extend(App.UserPref, {
           var widgets = misc.sortByOrder($("#widget_layout .widget").map(function () {
             return this.id;
           }), self.get('controller.widgets'));
-          self.get('controller').saveReorderedLayout(widgets);
+          self.get('controller').saveWidgetLayout(widgets);
         },
         activate: function (event, ui) {
           self.set('isMoving', true);

+ 0 - 113
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO_test.js

@@ -1,113 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_cpuWaitIO');
-
-describe('App.MainChartHeatmapCpuWaitIOMetric', function () {
-
-  var tests = [
-    {
-      json: {
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "cpu" : {
-                "cpu_wio" : 0.4
-              }
-            }
-          }
-        ]
-      },
-      m: 'One host',
-      e: {'dev01.hortonworks.com': '40.0'}
-    },
-    {
-      json: {
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "cpu" : {
-                "cpu_wio" : 0.4
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "cpu" : {
-                "cpu_wio" : 0.34566
-              }
-            }
-          }
-        ]
-      },
-      m: 'Two hosts',
-      e: {'dev01.hortonworks.com': '40.0', 'dev02.hortonworks.com': '34.6'}
-    },
-    {
-      json: {
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "cpu" : {
-                "cpu_wio" : 0.4
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "cpu" : {
-              }
-            }
-          }
-        ]
-      },
-      m: 'Two hosts, One without metric',
-      e: {'dev01.hortonworks.com': '40.0'}
-    }
-  ];
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapCpuWaitIOMetric = App.MainChartHeatmapCpuWaitIOMetric.create();
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapCpuWaitIOMetric.metricMapper(test.json);
-        expect(r).to.eql(test.e);
-      });
-    });
-
-  });
-
-});

+ 0 - 45
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread_test.js

@@ -1,45 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_bytesread');
-
-describe('App.MainChartHeatmapDFSBytesReadMetric', function () {
-
-  var tests = [
-    {i: 0, e: 0},
-    {i: 0.5 * 1024* 1024, e: 0.5},
-    {i: 1024* 1024, e: 1},
-    {i: 10.5 * 1024 * 1024,e: 10.5}
-  ];
-
-  describe('#transformValue()', function() {
-    var mainChartHeatmapDFSBytesReadMetric = App.MainChartHeatmapDFSBytesReadMetric.create();
-
-    tests.forEach(function(test) {
-      it(test.i + ' bytes to ' + test.e + ' MB', function() {
-        var r = mainChartHeatmapDFSBytesReadMetric.transformValue(test.i);
-        expect(r).to.eql(test.e);
-      });
-    });
-
-  });
-
-});

+ 0 - 45
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten_test.js

@@ -1,45 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_byteswritten');
-
-describe('App.MainChartHeatmapDFSBytesWrittenMetric', function () {
-
-  var tests = [
-    {i: 0, e: 0},
-    {i: 0.5 * 1024* 1024, e: 0.5},
-    {i: 1024* 1024, e: 1},
-    {i: 10.5 * 1024 * 1024,e: 10.5}
-  ];
-
-  describe('#transformValue()', function() {
-    var mainChartHeatmapDFSBytesWrittenMetric = App.MainChartHeatmapDFSBytesWrittenMetric.create();
-
-    tests.forEach(function(test) {
-      it(test.i + ' bytes to ' + test.e + ' MB', function() {
-        var r = mainChartHeatmapDFSBytesWrittenMetric.transformValue(test.i);
-        expect(r).to.eql(test.e);
-      });
-    });
-
-  });
-
-});

+ 0 - 115
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_dfs_test.js

@@ -1,115 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_dfs');
-
-describe('App.MainChartHeatmapDFSMetrics', function () {
-
-  var tests = [
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "gcTimeMillis" : 285
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 285},
-      m: 'One host_component'
-    },
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "gcTimeMillis" : 285
-              }
-            }
-          },
-          {
-            "HostRoles" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "gcTimeMillis" : 124
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 285, 'dev02.hortonworks.com': 124},
-      m: 'Two host_components'
-    },
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "gcTimeMillis" : 285
-              }
-            }
-          },
-          {
-            "HostRoles" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 285},
-      m: 'Two host_components, one without metric'
-    }
-  ];
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapDFSMetrics = App.MainChartHeatmapDFSMetrics.create();
-    mainChartHeatmapDFSMetrics.set('defaultMetric', 'metrics.jvm.gcTimeMillis');
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapDFSMetrics.metricMapper(test.json);
-        expect(r).to.eql(test.result);
-      });
-    });
-
-  });
-
-});

+ 0 - 116
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused_test.js

@@ -1,116 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_diskspaceused');
-
-describe('App.MainChartHeatmapDiskSpaceUsedMetric', function () {
-
-  var tests = Em.A([
-    {
-      json:{
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "disk" : {
-                "disk_free" : 89.973,
-                "disk_total" : 101.515
-              }
-            }
-          }
-        ]
-      },
-      m: 'One host',
-      e: {'dev01.hortonworks.com': 11.37}
-    },
-    {
-      json:{
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "disk" : {
-                "disk_free" : 89.973,
-                "disk_total" : 101.515
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "disk" : {
-                "disk_free" : 89.973,
-                "disk_total" : 101.515
-              }
-            }
-          }
-        ]
-      },
-      m: 'Two hosts',
-      e: {'dev01.hortonworks.com': 11.37, 'dev02.hortonworks.com': 11.37}
-    },
-    {
-      json:{
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "disk" : {
-                "disk_free" : 89.973,
-                "disk_total" : 101.515
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-
-            }
-          }
-        ]
-      },
-      m: 'Two hosts, One without metric',
-      e: {'dev01.hortonworks.com': 11.37}
-    }
-  ]);
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapDiskSpaceUsedMetric = App.MainChartHeatmapDiskSpaceUsedMetric.create();
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapDiskSpaceUsedMetric.metricMapper(test.json);
-        expect(r).to.eql(test.e);
-      });
-    });
-
-  });
-
-});

+ 0 - 125
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_hbase_test.js

@@ -1,125 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_hbase');
-
-describe('App.MainChartHeatmapHbaseMetrics', function () {
-
-  var tests = [
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "hbase" : {
-                "regionserver" : {
-                  "readRequestsCount" : 0.0
-                }
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 0},
-      m: 'One host_component'
-    },
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "hbase" : {
-                "regionserver" : {
-                  "readRequestsCount" : 0.0
-                }
-              }
-            }
-          },
-          {
-            "HostRoles" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "hbase" : {
-                "regionserver" : {
-                  "readRequestsCount" : 1.0
-                }
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 0, 'dev02.hortonworks.com': 1},
-      m: 'Two host_components'
-    },
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "hbase" : {
-                "regionserver" : {
-                  "readRequestsCount" : 0.0
-                }
-              }
-            }
-          },
-          {
-            "HostRoles" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "hbase" : {
-                "regionserver" : {
-
-                }
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 0},
-      m: 'Two host_components, one without metric'
-    }
-  ];
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapHbaseMetrics = App.MainChartHeatmapHbaseMetrics.create();
-    mainChartHeatmapHbaseMetrics.set('defaultMetric', 'metrics.hbase.regionserver.readRequestsCount');
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapHbaseMetrics.metricMapper(test.json);
-        expect(r).to.eql(test.result);
-      });
-    });
-
-  });
-
-});

+ 0 - 136
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused_test.js

@@ -1,136 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_memoryused');
-
-describe('App.MainChartHeatmapMemoryUsedMetric', function () {
-
-  var tests = [
-    {
-      json:{
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "memory" : {
-                "mem_buffers" : 109888.0,
-                "mem_cached" : 1965624.0,
-                "mem_free" : 261632.0,
-                "mem_shared" : 0.0,
-                "mem_total" : 6123776.0,
-                "swap_free" : 4126820.0,
-                "swap_total" : 4128760.0
-              }
-            }
-          }
-        ]
-      },
-      m: 'One host',
-      e: {'dev01.hortonworks.com': '63.6'}
-    },
-    {
-      json:{
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "memory" : {
-                "mem_buffers" : 109888.0,
-                "mem_cached" : 1965624.0,
-                "mem_free" : 261632.0,
-                "mem_shared" : 0.0,
-                "mem_total" : 6123776.0,
-                "swap_free" : 4126820.0,
-                "swap_total" : 4128760.0
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "memory" : {
-                "mem_buffers" : 109888.0,
-                "mem_cached" : 1965624.0,
-                "mem_free" : 261632.0,
-                "mem_shared" : 0.0,
-                "mem_total" : 6123776.0,
-                "swap_free" : 4126820.0,
-                "swap_total" : 4128760.0
-              }
-            }
-          }
-        ]
-      },
-      m: 'Two hosts',
-      e: {'dev01.hortonworks.com': '63.6', 'dev02.hortonworks.com': '63.6'}
-    },
-    {
-      json:{
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "memory" : {
-                "mem_buffers" : 109888.0,
-                "mem_cached" : 1965624.0,
-                "mem_free" : 261632.0,
-                "mem_shared" : 0.0,
-                "mem_total" : 6123776.0,
-                "swap_free" : 4126820.0,
-                "swap_total" : 4128760.0
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-
-            }
-          }
-        ]
-      },
-      m: 'Two hosts, One without metric',
-      e: {'dev01.hortonworks.com': '63.6'}
-    }
-  ];
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapMemoryUsedMetric = App.MainChartHeatmapMemoryUsedMetric.create();
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapMemoryUsedMetric.metricMapper(test.json);
-        expect(r).to.eql(test.e);
-      });
-    });
-
-  });
-
-});

+ 0 - 111
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_processrun_test.js

@@ -1,111 +0,0 @@
-/**
- * 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');
-
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_processrun');
-
-describe('App.MainChartHeatmapProcessRunMetric', function () {
-
-  var tests = [
-    {
-      json: {
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "process" : {
-                "proc_run" : 0.0
-              }
-            }
-          }
-        ]
-      },
-      m: 'One host',
-      result: {'dev01.hortonworks.com': '0.0'}
-    },
-    {
-      json: {
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "process" : {
-                "proc_run" : 0.1
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "process" : {
-                "proc_run" : 0.46
-              }
-            }
-          }
-        ]
-      },
-      m: 'Two hosts',
-      result: {'dev01.hortonworks.com': '0.1', 'dev02.hortonworks.com': '0.5'}
-    },
-    {
-      json: {
-        "items" : [
-          {
-            "Hosts" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "process" : {
-                "proc_run" : 0.99
-              }
-            }
-          },
-          {
-            "Hosts" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "process" : {
-              }
-            }
-          }
-        ]
-      },
-      m: 'Two hosts, One without metric',
-      result: {'dev01.hortonworks.com': '1.0'}
-    }
-  ];
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapProcessRunMetric = App.MainChartHeatmapProcessRunMetric.create();
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapProcessRunMetric.metricMapper(test.json);
-        expect(r).to.eql(test.result);
-      });
-    });
-  });
-});

+ 0 - 43
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_test.js

@@ -43,30 +43,6 @@ describe('MainChartHeatmapMetric', function () {
     });
   });
 
-  describe('#refreshHostSlots', function() {
-    beforeEach(function() {
-      sinon.stub(App.ajax, 'send', Em.K);
-    });
-
-    afterEach(function() {
-      App.ajax.send.restore();
-    });
-
-    it('Should load proper URL', function() {
-      mainChartHeatmapMetric.set('ajaxData', {
-        serviceName: 'SERVICE',
-        componentName: 'COMPONENT'
-      });
-      mainChartHeatmapMetric.set('defaultMetric', 'default.metric');
-      mainChartHeatmapMetric.refreshHostSlots();
-      expect(App.ajax.send.getCall(0).args[0].data).to.eql({
-        "metricName": "default/metric",
-        "serviceName": "SERVICE",
-        "componentName": "COMPONENT"
-      });
-      expect(App.ajax.send.getCall(0).args[0].name).to.equal('hosts.metrics');
-    });
-  });
 
   describe('#slotDefinitions', function () {
     beforeEach(function () {
@@ -304,23 +280,4 @@ describe('MainChartHeatmapMetric', function () {
     });
   });
 
-  describe('#refreshHostSlotsSuccessCallback()', function () {
-    it('launch metricMapper with recieved data', function () {
-      sinon.stub(mainChartHeatmapMetric, 'metricMapper').returns({'host1': 1});
-      mainChartHeatmapMetric.refreshHostSlotsSuccessCallback({data: 'data'});
-      expect(mainChartHeatmapMetric.get('hostToValueMap')).to.eql({'host1': 1});
-      expect(mainChartHeatmapMetric.get('loading')).to.be.false;
-      expect(mainChartHeatmapMetric.metricMapper.calledWith({data: 'data'})).to.be.true;
-      mainChartHeatmapMetric.metricMapper.restore();
-    });
-  });
-
-  describe('#refreshHostSlotsErrorCallback()', function () {
-    it('', function () {
-      mainChartHeatmapMetric.set('loading', undefined);
-      mainChartHeatmapMetric.refreshHostSlotsErrorCallback({data: 'data'});
-      expect(mainChartHeatmapMetric.get('loading')).to.be.false;
-    });
-  });
-
 });

+ 0 - 128
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed_test.js

@@ -1,128 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_ResourceUsed');
-
-describe('App.MainChartHeatmapYarnResourceUsedMetric', function () {
-
-  var mainChartHeatmapYarnResourceUsedMetric = App.MainChartHeatmapYarnResourceUsedMetric.create({});
-
-  describe('#metricMapper', function () {
-    var tests = [
-      {
-        m: 'Correct JSON #1',
-        i: {
-          ServiceComponentInfo: {
-            cluster_name: "c1",
-            component_name: "NODEMANAGER",
-            service_name: "YARN"
-          },
-          host_components: [{
-            HostRoles: {
-              cluster_name: "c1",
-              component_name: "NODEMANAGER",
-              host_name: "host1"
-            },
-            metrics: {
-              yarn: {
-                AllocatedGB: 0,
-                AvailableGB: 2
-              }
-            }
-          }]
-        },
-        e: {
-          length: 1,
-          val: '0.0',
-          host: 'host1'
-        }
-      },
-      {
-        m: 'Correct JSON #2',
-        i: {
-          ServiceComponentInfo: {
-            cluster_name: "c1",
-            component_name: "NODEMANAGER",
-            service_name: "YARN"
-          },
-          host_components: [{
-            HostRoles: {
-              cluster_name: "c1",
-              component_name: "NODEMANAGER",
-              host_name: "host1"
-            },
-            metrics: {
-              yarn: {
-                AllocatedGB: 1,
-                AvailableGB: 2
-              }
-            }
-          }]
-        },
-        e: {
-          length: 1,
-          val: '33.3',
-          host: 'host1'
-        }
-      },
-      {
-        m: 'Correct JSON #3',
-        i: {
-          ServiceComponentInfo: {
-            cluster_name: "c1",
-            component_name: "NODEMANAGER",
-            service_name: "YARN"
-          },
-          host_components: [{
-            HostRoles: {
-              cluster_name: "c1",
-              component_name: "NODEMANAGER",
-              host_name: "host1"
-            },
-            metrics: {
-              yarn: {
-                AllocatedGB: 0,
-                AvailableGB: 0
-              }
-            }
-          }]
-        },
-        e: {
-          length: 1,
-          val: 'Unknown',
-          host: 'host1'
-        }
-      }
-    ];
-    tests.forEach(function(test) {
-      it(test.m, function () {
-        var result = mainChartHeatmapYarnResourceUsedMetric.metricMapper(test.i),
-          length = Em.keys(result).length;
-        expect(length).to.equal(test.e.length);
-        if (test.e.host) {
-          expect(result.hasOwnProperty(test.e.host)).to.equal(true);
-          expect(result[test.e.host]).to.equal(test.e.val);
-        }
-      });
-    });
-  });
-
-});

+ 0 - 115
ambari-web/test/controllers/main/charts/heatmap_metrics/heatmap_metric_yarn_test.js

@@ -1,115 +0,0 @@
-/**
- * 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');
-require('messages');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric');
-require('controllers/main/charts/heatmap_metrics/heatmap_metric_yarn');
-
-describe('App.MainChartHeatmapYarnMetrics', function () {
-
-  var tests = [
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "memHeapUsedM" : 10
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 10},
-      m: 'One host_component'
-    },
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "memHeapUsedM" : 10
-              }
-            }
-          },
-          {
-            "HostRoles" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "memHeapUsedM" : 20
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 10, 'dev02.hortonworks.com': 20},
-      m: 'Two host_components'
-    },
-    {
-      json: {
-        "host_components" : [
-          {
-            "HostRoles" : {
-              "host_name" : "dev01.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-                "memHeapUsedM" : 10
-              }
-            }
-          },
-          {
-            "HostRoles" : {
-              "host_name" : "dev02.hortonworks.com"
-            },
-            "metrics" : {
-              "jvm" : {
-
-              }
-            }
-          }
-        ]
-      },
-      result: {'dev01.hortonworks.com': 10},
-      m: 'Two host_components, one without metric'
-    }
-  ];
-
-  describe('#metricMapper()', function() {
-    var mainChartHeatmapYarnMetrics = App.MainChartHeatmapYarnMetrics.create();
-    mainChartHeatmapYarnMetrics.set('defaultMetric', 'metrics.jvm.memHeapUsedM');
-
-    tests.forEach(function(test) {
-      it(test.m, function() {
-        var r = mainChartHeatmapYarnMetrics.metricMapper(test.json);
-        expect(r).to.eql(test.result);
-      });
-    });
-
-  });
-
-});

+ 22 - 30
ambari-web/test/controllers/main/charts/heatmap_test.js

@@ -47,41 +47,33 @@ describe('MainChartsHeatmapController', function () {
   });
 
   describe('#showHeatMapMetric()', function () {
-    var controller = App.MainChartsHeatmapController.create({
-      allMetrics: [],
-      selectedMetric: Ember.Object.create({maximumValue: 100}),
-      loadMetrics: function () {
-      }
+    beforeEach(function () {
+      sinon.stub(App.ajax, 'send', function () {
+        return {
+          done: function (callback) {
+            callback();
+          }
+        }
+      });
     });
-    controller.set("selectedMetric", 100);
-    it('should not set selectedMetric event.context if it is not defined', function () {
-      controller.showHeatMapMetric({});
-      expect(controller.get('selectedMetric')).to.equal(100);
-    });
-    it('should set selectedMetric event.context if it is defined', function () {
-      controller.showHeatMapMetric({context: 5});
-      expect(controller.get('selectedMetric')).to.equal(5);
+
+    afterEach(function () {
+      App.ajax.send.restore();
     });
-  });
 
-  describe('#loadMetrics()', function () {
     var controller = App.MainChartsHeatmapController.create({
-      testPassed: false,
-      allMetrics: [],
-      inputMaximum: 10
+      activeWidgetLayout: Em.Object.create({
+        displayName: 'widget',
+        id: '1',
+        scope: 'CLUSTER',
+        layoutName: 'defualt_layout',
+        sectionName: 'default_section'
+      })
     });
-    controller.set('selectedMetric', Ember.Object.create({
-      maximumValue: 100,
-      refreshHostSlots: function () {
-        controller.set('testPassed', true);
-      }
-    }));
-    controller.loadMetrics();
-    it('should set inputMaximum as selectedMetric.maximumValue', function () {
-      expect(controller.get('inputMaximum')).to.equal(100);
-    });
-    it('should call refreshHostSlots from selectedMetric', function () {
-      expect(controller.get('testPassed')).to.equal(true);
+
+    it('should call App.ajax', function () {
+      controller.showHeatMapMetric({context:{id: 2}});
+      expect(App.ajax.send.called).to.be.true;
     });
   });