Browse Source

AMBARI-1058. Implement data loading. (yusaku)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/branches/AMBARI-666@1418895 13f79535-47bb-0310-9956-ffa450edef68
Yusaku Sako 12 years ago
parent
commit
3122e9d47d
84 changed files with 3850 additions and 1996 deletions
  1. 2 0
      AMBARI-666-CHANGES.txt
  2. 426 0
      ambari-web/app/assets/data/alerts/alerts.json
  3. 338 0
      ambari-web/app/assets/data/background_operations/list_on_start.json
  4. 225 929
      ambari-web/app/assets/data/dashboard/services.json
  5. 0 320
      ambari-web/app/assets/data/dashboard/servicesHealth.json
  6. 126 0
      ambari-web/app/assets/data/hosts/hosts.json
  7. 12 1
      ambari-web/app/controllers/installer.js
  8. 65 13
      ambari-web/app/controllers/main.js
  9. 7 10
      ambari-web/app/controllers/main/apps_controller.js
  10. 25 2
      ambari-web/app/controllers/main/host.js
  11. 143 2
      ambari-web/app/controllers/main/service/info/configs.js
  12. 1 1
      ambari-web/app/controllers/main/service/info/summary.js
  13. 61 0
      ambari-web/app/controllers/main/service/item.js
  14. 11 10
      ambari-web/app/controllers/wizard/step10_controller.js
  15. 6 1
      ambari-web/app/controllers/wizard/step2_controller.js
  16. 8 8
      ambari-web/app/controllers/wizard/step8_controller.js
  17. 12 12
      ambari-web/app/controllers/wizard/step9_controller.js
  18. 1 1
      ambari-web/app/data/service_components.js
  19. 7 2
      ambari-web/app/initialize.js
  20. 35 0
      ambari-web/app/mappers/alerts_mapper.js
  21. 38 0
      ambari-web/app/mappers/hosts_mapper.js
  22. 45 0
      ambari-web/app/mappers/server_data_mapper.js
  23. 116 0
      ambari-web/app/mappers/services_mapper.js
  24. 22 17
      ambari-web/app/messages.js
  25. 2 1
      ambari-web/app/models.js
  26. 8 104
      ambari-web/app/models/alert.js
  27. 1 7
      ambari-web/app/models/app.js
  28. 16 1
      ambari-web/app/models/job.js
  29. 155 0
      ambari-web/app/models/protoRelations.js
  30. 61 48
      ambari-web/app/models/run.js
  31. 5 2
      ambari-web/app/models/service.js
  32. 12 12
      ambari-web/app/router.js
  33. 0 1
      ambari-web/app/routes/add_host_routes.js
  34. 0 1
      ambari-web/app/routes/add_service_routes.js
  35. 23 17
      ambari-web/app/routes/installer.js
  36. 7 6
      ambari-web/app/routes/main.js
  37. 102 71
      ambari-web/app/styles/application.less
  38. 15 4
      ambari-web/app/styles/apps.less
  39. 2 4
      ambari-web/app/templates/login.hbs
  40. 6 6
      ambari-web/app/templates/main/apps.hbs
  41. 4 4
      ambari-web/app/templates/main/apps/item/bar.hbs
  42. 2 2
      ambari-web/app/templates/main/apps/item/dag.hbs
  43. 2 2
      ambari-web/app/templates/main/apps/list_row.hbs
  44. 26 26
      ambari-web/app/templates/main/background_operations_popup.hbs
  45. 3 3
      ambari-web/app/templates/main/dashboard.hbs
  46. 4 4
      ambari-web/app/templates/main/dashboard/service/hbase.hbs
  47. 4 4
      ambari-web/app/templates/main/dashboard/service/hdfs.hbs
  48. 4 4
      ambari-web/app/templates/main/dashboard/service/hive.hbs
  49. 4 4
      ambari-web/app/templates/main/dashboard/service/mapreduce.hbs
  50. 4 4
      ambari-web/app/templates/main/dashboard/service/oozie.hbs
  51. 4 4
      ambari-web/app/templates/main/dashboard/service/zookeeper.hbs
  52. 9 32
      ambari-web/app/templates/main/host.hbs
  53. 1 1
      ambari-web/app/templates/main/host/details.hbs
  54. 189 104
      ambari-web/app/templates/main/service/info/configs.hbs
  55. 54 6
      ambari-web/app/templates/main/service/info/summary.hbs
  56. 10 21
      ambari-web/app/templates/main/service/item.hbs
  57. 1 1
      ambari-web/app/templates/main/service/menu_item.hbs
  58. 47 0
      ambari-web/app/templates/main/test.hbs
  59. 8 3
      ambari-web/app/templates/wizard/step2.hbs
  60. 1 1
      ambari-web/app/templates/wizard/step9.hbs
  61. 133 3
      ambari-web/app/utils/data_table.js
  62. 11 4
      ambari-web/app/utils/db.js
  63. 1 1
      ambari-web/app/utils/graph.js
  64. 119 0
      ambari-web/app/utils/http_client.js
  65. 36 0
      ambari-web/app/utils/misc.js
  66. 2 0
      ambari-web/app/views.js
  67. 72 0
      ambari-web/app/views/common/combobox.js
  68. 6 1
      ambari-web/app/views/login.js
  69. 3 3
      ambari-web/app/views/main/apps/item/bar_view.js
  70. 12 2
      ambari-web/app/views/main/apps/item/dag_view.js
  71. 127 37
      ambari-web/app/views/main/apps_view.js
  72. 23 27
      ambari-web/app/views/main/dashboard/service.js
  73. 32 12
      ambari-web/app/views/main/host.js
  74. 18 3
      ambari-web/app/views/main/service/info/configs.js
  75. 12 2
      ambari-web/app/views/main/service/info/summary.js
  76. 24 0
      ambari-web/app/views/main/test.js
  77. 39 1
      ambari-web/app/views/wizard/step2_view.js
  78. 2 0
      ambari-web/config.coffee
  79. 1 2
      ambari-web/package.json
  80. 1 1
      ambari-web/pom.xml
  81. 217 0
      ambari-web/vendor/scripts/bootstrap-combobox.js
  82. 53 53
      ambari-web/vendor/scripts/jquery.dataTables.js
  83. 198 0
      ambari-web/vendor/scripts/jquery.periodic.js
  84. 180 0
      ambari-web/vendor/styles/bootstrap-combobox.css

+ 2 - 0
AMBARI-666-CHANGES.txt

@@ -392,6 +392,8 @@ AMBARI-666 branch (unreleased changes)
 
 
   IMPROVEMENTS
   IMPROVEMENTS
 
 
+  AMBARI-1058. Implement data loading (yusaku)
+
   AMBARI-956. On unavailability of non-master components, host with least
   AMBARI-956. On unavailability of non-master components, host with least
   number of master components should install all slave and client components. 
   number of master components should install all slave and client components. 
   (Jaimin Jetly via yusaku)
   (Jaimin Jetly via yusaku)

+ 426 - 0
ambari-web/app/assets/data/alerts/alerts.json

@@ -0,0 +1,426 @@
+{"alerts": [
+  {
+    "service_description": "Process down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.001 second response time on port 50010",
+    "last_hard_state_change": "1350378326",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Storage full",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: Capacity:[], Remaining Capacity:[], percent_full:[0]",
+    "last_hard_state_change": "1350378331",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878395",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878395",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Ganglia [gmetad] Process down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.001 second response time on port 8651",
+    "last_hard_state_change": "1350378335",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878575",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878575",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Ganglia collector [gmond] Process down alert for jobtracker",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.003 second response time on port 8662",
+    "last_hard_state_change": "1350378340",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878575",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878575",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Ganglia collector [gmond] Process down alert for namenode",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.003 second response time on port 8661",
+    "last_hard_state_change": "1350378344",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878575",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878575",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Ganglia collector [gmond] Process down alert for slaves",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.004 second response time on port 8660",
+    "last_hard_state_change": "1350378349",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878575",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878575",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Corrupt\/Missing blocks",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: corrupt_blocks:<0>, missing_blocks:<0>, total_blocks:<135>",
+    "last_hard_state_change": "1350933589",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878469",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "1350933469",
+    "is_flapping": "0",
+    "last_check": "1351878469",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "HDFS Capacity utilization",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: DFSUsedGB:<0>, DFSTotalGB:<784.3>",
+    "last_hard_state_change": "1350378358",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878395",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878395",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Namenode RPC Latency",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: RpcQueueTime_avg_time:<0> Secs, RpcProcessingTime_avg_time:<0> Secs",
+    "last_hard_state_change": "1350378362",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878395",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878395",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Percent DataNodes down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: total:<1>, affected:<0>",
+    "last_hard_state_change": "1350378367",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878560",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878560",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Percent DataNodes storage full",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: total:<1>, affected:<0>",
+    "last_hard_state_change": "1350378371",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878469",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878469",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "JobHistory Web UI down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: Successfully accessed jobhistory Web UI",
+    "last_hard_state_change": "1350378376",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "1351216729",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "MAPREDUCE"
+  },
+  {
+    "service_description": "JobTracker Web UI down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: Successfully accessed jobtracker Web UI",
+    "last_hard_state_change": "1350378380",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "1351216729",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "MAPREDUCE"
+  },
+  {
+    "service_description": "Jobtracker CPU utilization",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "2 CPU, average load 3.0% < 200% : OK",
+    "last_hard_state_change": "1350378385",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878395",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878395",
+    "service_type": "MAPREDUCE"
+  },
+  {
+    "service_description": "Jobtracker Process down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.003 second response time on port 50030",
+    "last_hard_state_change": "1351216775",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878575",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "1351216745",
+    "is_flapping": "0",
+    "last_check": "1351878575",
+    "service_type": "MAPREDUCE"
+  },
+  {
+    "service_description": "JobTracker RPC Latency",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: RpcQueueTime_avg_time:<0> Secs, RpcProcessingTime_avg_time:<0.06> Secs",
+    "last_hard_state_change": "1350378394",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878395",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878395",
+    "service_type": "MAPREDUCE"
+  },
+  {
+    "service_description": "Percent TaskTrackers down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: total:<1>, affected:<0>",
+    "last_hard_state_change": "1351216880",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878560",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "1351216850",
+    "is_flapping": "0",
+    "last_check": "1351878560",
+    "service_type": "MAPREDUCE"
+  },
+  {
+    "service_description": "Nagios status log staleness",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "NAGIOS OK: 2 processes, status log updated 9 seconds ago",
+    "last_hard_state_change": "1350937033",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878433",
+    "last_time_warning": "1350936733",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878433",
+    "service_type": "UNKNOWN"
+  },
+  {
+    "service_description": "Namenode Edit logs directory status",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: All Namenode directories are active",
+    "last_hard_state_change": "1350378408",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878560",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878560",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Namenode Host CPU utilization",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "2 CPU, average load 3.0% < 200% : OK",
+    "last_hard_state_change": "1350378412",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878412",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878412",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Namenode Process down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.000 second response time on port 8020",
+    "last_hard_state_change": "1350378417",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878559",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878559",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Namenode Web UI down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: Successfully accessed namenode Web UI",
+    "last_hard_state_change": "1350378421",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Secondary Namenode Process down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.001 second response time on port 50090",
+    "last_hard_state_change": "1350378426",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878560",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878560",
+    "service_type": "HDFS"
+  },
+  {
+    "service_description": "Oozie status check",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "OK: Oozie server status [System mode: NORMAL]",
+    "last_hard_state_change": "1351217029",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "1351216969",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "OOZIE"
+  },
+  {
+    "service_description": "Puppet agent down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.001 second response time on port 8139",
+    "last_hard_state_change": "1350378435",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "0",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "PUPPET"
+  },
+  {
+    "service_description": "Process down",
+    "host_name": "host",
+    "current_attempt": "1",
+    "current_state": "0",
+    "plugin_output": "TCP OK - 0.000 second response time on port 50060",
+    "last_hard_state_change": "1351216849",
+    "last_hard_state": "0",
+    "last_time_ok": "1351878529",
+    "last_time_warning": "0",
+    "last_time_unknown": "0",
+    "last_time_critical": "1351216789",
+    "is_flapping": "0",
+    "last_check": "1351878529",
+    "service_type": "UNKNOWN"
+  }
+], "hostcounts": {
+  "up_hosts": 1,
+  "down_hosts": 0
+}, "servicestates": {
+  "PUPPET": 0,
+  "MAPREDUCE": "0",
+  "HDFS": "0",
+  "OOZIE": "0"
+}}

+ 338 - 0
ambari-web/app/assets/data/background_operations/list_on_start.json

@@ -0,0 +1,338 @@
+{
+  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/?fields=tasks/*",
+  "items" : [
+    {
+      "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/3",
+      "Requests" : {
+        "id" : 3,
+        "cluster_name" : "mycluster"
+      },
+      "tasks" : [
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/3/tasks/16",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "QUEUED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 16,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 3,
+            "command" : "STOP",
+            "role" : "NAMENODE",
+            "start_time" : 1352125378300,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/3/tasks/15",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 15,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 3,
+            "command" : "STOP",
+            "role" : "DATANODE",
+            "start_time" : 1352125378280,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/3/tasks/17",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 17,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 3,
+            "command" : "STOP",
+            "role" : "SECONDARY_NAMENODE",
+            "start_time" : 1352125378315,
+            "stage_id" : 1
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2",
+      "Requests" : {
+        "id" : 2,
+        "cluster_name" : "mycluster"
+      },
+      "tasks" : [
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/11",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 11,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "START",
+            "role" : "JOBTRACKER",
+            "start_time" : 1352119106491,
+            "stage_id" : 2
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/14",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 14,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "EXECUTE",
+            "role" : "MAPREDUCE_SERVICE_CHECK",
+            "start_time" : 1352119157294,
+            "stage_id" : 3
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/13",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 13,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "START",
+            "role" : "TASKTRACKER",
+            "start_time" : 1352119106518,
+            "stage_id" : 2
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/12",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 12,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "START",
+            "role" : "SECONDARY_NAMENODE",
+            "start_time" : 1352119106506,
+            "stage_id" : 2
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/9",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 9,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "START",
+            "role" : "NAMENODE",
+            "start_time" : 1352119024782,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/8",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 8,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "START",
+            "role" : "DATANODE",
+            "start_time" : 1352119024765,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/2/tasks/10",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 10,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 1,
+            "request_id" : 2,
+            "command" : "EXECUTE",
+            "role" : "HDFS_SERVICE_CHECK",
+            "start_time" : 1352119106480,
+            "stage_id" : 2
+          }
+        }
+      ]
+    },
+    {
+      "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1",
+      "Requests" : {
+        "id" : 1,
+        "cluster_name" : "mycluster"
+      },
+      "tasks" : [
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/1",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 1,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "DATANODE",
+            "start_time" : 1352118607290,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/4",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 4,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "MAPREDUCE_CLIENT",
+            "start_time" : 1352118607672,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/5",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 5,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "NAMENODE",
+            "start_time" : 1352118607808,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/3",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 3,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "JOBTRACKER",
+            "start_time" : 1352118607566,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/7",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 7,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "TASKTRACKER",
+            "start_time" : 1352118608124,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/2",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 2,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "HDFS_CLIENT",
+            "start_time" : 1352118607469,
+            "stage_id" : 1
+          }
+        },
+        {
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/requests/1/tasks/6",
+          "Tasks" : {
+            "exit_code" : 0,
+            "stdout" : "Output",
+            "status" : "COMPLETED",
+            "stderr" : "none",
+            "host_name" : "dev.hortonworks.com",
+            "id" : 6,
+            "cluster_name" : "mycluster",
+            "attempt_cnt" : 2,
+            "request_id" : 1,
+            "command" : "INSTALL",
+            "role" : "SECONDARY_NAMENODE",
+            "start_time" : 1352118607958,
+            "stage_id" : 1
+          }
+        }
+      ]
+    }
+  ]
+}

+ 225 - 929
ambari-web/app/assets/data/dashboard/services.json

@@ -1,43 +1,36 @@
 {
 {
-  "href" : "http://ambari/clusters/mycluster/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=*,components/*,components/host_components/*",
+  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/host_components/*",
   "items" : [
   "items" : [
     {
     {
-      "href" : "http://ambari/clusters/mycluster/services/HBASE",
-      "Services" : {
-        "display_name" : "HBase",
-        "description" : "Apache HDFS-based Non-relational Distributed Database",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": false, \"editable\": true, \"noDisplay\": false }"
-      },
+      "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE",
       "ServiceInfo" : {
       "ServiceInfo" : {
         "cluster_name" : "mycluster",
         "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "HBASE"
+        "service_name" : "MAPREDUCE"
       },
       },
       "components" : [
       "components" : [
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_MASTER",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE/components/MAPREDUCE_CLIENT",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
-            "component_name" : "HBASE_MASTER",
-            "service_name" : "HBASE"
+            "component_name" : "MAPREDUCE_CLIENT",
+            "service_name" : "MAPREDUCE"
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HBASE_MASTER",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/MAPREDUCE_CLIENT",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "5",
-                "component_name" : "HBASE_MASTER",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "state" : "INSTALLED",
+                "component_name" : "MAPREDUCE_CLIENT",
+                "host_name" : "dev.hortonworks.com"
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_MASTER",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE/components/MAPREDUCE_CLIENT",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
-                    "component_name" : "HBASE_MASTER",
-                    "service_name" : "HBASE"
+                    "component_name" : "MAPREDUCE_CLIENT",
+                    "service_name" : "MAPREDUCE"
                   }
                   }
                 }
                 }
               ]
               ]
@@ -45,149 +38,81 @@
           ]
           ]
         },
         },
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_REGIONSERVER",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE/components/JOBTRACKER",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
-            "component_name" : "HBASE_REGIONSERVER",
-            "service_name" : "HBASE"
+            "component_name" : "JOBTRACKER",
+            "service_name" : "MAPREDUCE"
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HBASE_REGIONSERVER",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/JOBTRACKER",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "24",
-                "component_name" : "HBASE_REGIONSERVER",
                 "state" : "STARTED",
                 "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_REGIONSERVER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "HBASE_REGIONSERVER",
-                    "service_name" : "HBASE"
-                  }
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "HBASE_CLIENT",
-            "service_name" : "HBASE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HBASE_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "29",
-                "component_name" : "HBASE_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_CLIENT",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "HBASE_CLIENT",
-                    "service_name" : "HBASE"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/PIG",
-      "Services" : {
-        "display_name" : "Pig",
-        "description" : "Platform for Analyzing Large Data Sets",
-        "attributes" : "{ \"runnable\": false, \"mustInstall\": false, \"editable\": true, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "INSTALLED",
-        "service_name" : "PIG"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/PIG/components/PIG_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "PIG_CLIENT",
-            "service_name" : "PIG"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/PIG_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "30",
-                "component_name" : "PIG_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "component_name" : "JOBTRACKER",
+                "host_name" : "dev.hortonworks.com"
               },
               },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/PIG/components/PIG_CLIENT",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "PIG_CLIENT",
-                    "service_name" : "PIG"
-                  }
+              "metrics" : {
+                "rpc" : {
+                  "rpcAuthorizationSuccesses" : 0,
+                  "SentBytes" : 32961793,
+                  "rpcAuthorizationFailures" : 0,
+                  "ReceivedBytes" : 95243938,
+                  "NumOpenConnections" : 0,
+                  "callQueueLen" : 0,
+                  "RpcQueueTime_num_ops" : 307991,
+                  "rpcAuthenticationSuccesses" : 0,
+                  "RpcProcessingTime_num_ops" : 307991,
+                  "RpcProcessingTime_avg_time" : 0.02941176470588236,
+                  "rpcAuthenticationFailures" : 0,
+                  "RpcQueueTime_avg_time" : 0.14705882352941177
+                },
+                "jvm" : {
+                  "memHeapCommittedM" : 185.1875,
+                  "logFatal" : 0,
+                  "threadsBlocked" : 0,
+                  "gcCount" : 24,
+                  "threadsWaiting" : 22,
+                  "logWarn" : 0,
+                  "logError" : 0,
+                  "memNonHeapCommittedM" : 23.625,
+                  "memNonHeapUsedM" : 23.226303,
+                  "gcTimeMillis" : 714,
+                  "logInfo" : 3,
+                  "threadsNew" : 0,
+                  "memHeapUsedM" : 27.627754,
+                  "threadsTerminated" : 0,
+                  "threadsTimedWaiting" : 8,
+                  "threadsRunnable" : 6
+                },
+                "metricssystem" : {
+                  "dropped_pub_all" : 0,
+                  "num_sources" : 6,
+                  "publish_max_time" : 6.0,
+                  "publish_num_ops" : 9269,
+                  "snapshot_stdev_time" : 0.0,
+                  "snapshot_num_ops" : 64889,
+                  "publish_stdev_time" : 0.0,
+                  "num_sinks" : 1,
+                  "publish_imin_time" : 0.0,
+                  "snapshot_min_time" : 0.0,
+                  "snapshot_imin_time" : 0.0,
+                  "snapshot_imax_time" : 1.401298464324817E-45,
+                  "publish_avg_time" : 0.0,
+                  "publish_min_time" : 0.0,
+                  "snapshot_max_time" : 177.0,
+                  "publish_imax_time" : 1.401298464324817E-45,
+                  "snapshot_avg_time" : 0.0
                 }
                 }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/TEMPLETON",
-      "Services" : {
-        "display_name" : "Templeton",
-        "description" : "Webservice APIs for Apache Hadoop",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": false, \"editable\": true, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "TEMPLETON"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/TEMPLETON/components/TEMPLETON_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "TEMPLETON_CLIENT",
-            "service_name" : "TEMPLETON"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/TEMPLETON_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "34",
-                "component_name" : "TEMPLETON_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/TEMPLETON/components/TEMPLETON_CLIENT",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE/components/JOBTRACKER",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
-                    "component_name" : "TEMPLETON_CLIENT",
-                    "service_name" : "TEMPLETON"
+                    "component_name" : "JOBTRACKER",
+                    "service_name" : "MAPREDUCE"
                   }
                   }
                 }
                 }
               ]
               ]
@@ -195,29 +120,81 @@
           ]
           ]
         },
         },
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/TEMPLETON/components/TEMPLETON_SERVER",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE/components/TASKTRACKER",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
-            "component_name" : "TEMPLETON_SERVER",
-            "service_name" : "TEMPLETON"
+            "component_name" : "TASKTRACKER",
+            "service_name" : "MAPREDUCE"
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/TEMPLETON_SERVER",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/TASKTRACKER",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "8",
-                "component_name" : "TEMPLETON_SERVER",
                 "state" : "STARTED",
                 "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "component_name" : "TASKTRACKER",
+                "host_name" : "dev.hortonworks.com"
+              },
+              "metrics" : {
+                "rpc" : {
+                  "rpcAuthorizationSuccesses" : 0,
+                  "SentBytes" : 0,
+                  "rpcAuthorizationFailures" : 0,
+                  "ReceivedBytes" : 0,
+                  "NumOpenConnections" : 0,
+                  "callQueueLen" : 0,
+                  "RpcQueueTime_num_ops" : 0,
+                  "rpcAuthenticationSuccesses" : 0,
+                  "RpcProcessingTime_num_ops" : 0,
+                  "RpcProcessingTime_avg_time" : 0.0,
+                  "rpcAuthenticationFailures" : 0,
+                  "RpcQueueTime_avg_time" : 0.0
+                },
+                "jvm" : {
+                  "memHeapCommittedM" : 45.5625,
+                  "logFatal" : 0,
+                  "threadsBlocked" : 0,
+                  "gcCount" : 3433,
+                  "threadsWaiting" : 15,
+                  "logWarn" : 0,
+                  "logError" : 0,
+                  "memNonHeapCommittedM" : 23.1875,
+                  "memNonHeapUsedM" : 21.687134,
+                  "gcTimeMillis" : 2142,
+                  "logInfo" : 3,
+                  "threadsNew" : 0,
+                  "memHeapUsedM" : 3.5596008,
+                  "threadsTerminated" : 0,
+                  "threadsTimedWaiting" : 6,
+                  "threadsRunnable" : 6
+                },
+                "metricssystem" : {
+                  "dropped_pub_all" : 0,
+                  "num_sources" : 6,
+                  "publish_max_time" : 21.0,
+                  "publish_num_ops" : 9267,
+                  "snapshot_stdev_time" : 0.0,
+                  "snapshot_num_ops" : 64875,
+                  "publish_stdev_time" : 0.0,
+                  "num_sinks" : 1,
+                  "publish_imin_time" : 1.0,
+                  "snapshot_min_time" : 0.0,
+                  "snapshot_imin_time" : 0.0,
+                  "snapshot_imax_time" : 1.401298464324817E-45,
+                  "publish_avg_time" : 1.0,
+                  "publish_min_time" : 0.0,
+                  "snapshot_max_time" : 5.0,
+                  "publish_imax_time" : 1.0,
+                  "snapshot_avg_time" : 0.0
+                }
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/TEMPLETON/components/TEMPLETON_SERVER",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/MAPREDUCE/components/TASKTRACKER",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
-                    "component_name" : "TEMPLETON_SERVER",
-                    "service_name" : "TEMPLETON"
+                    "component_name" : "TASKTRACKER",
+                    "service_name" : "MAPREDUCE"
                   }
                   }
                 }
                 }
               ]
               ]
@@ -227,42 +204,35 @@
       ]
       ]
     },
     },
     {
     {
-      "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER",
-      "Services" : {
-        "display_name" : "ZooKeeper",
-        "description" : "Centralized Service for Configuration Management and Distribution Synchronization",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": false, \"editable\": false, \"noDisplay\": false }"
-      },
+      "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS",
       "ServiceInfo" : {
       "ServiceInfo" : {
         "cluster_name" : "mycluster",
         "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "ZOOKEEPER"
+        "service_name" : "HDFS"
       },
       },
       "components" : [
       "components" : [
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_SERVER",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/SECONDARY_NAMENODE",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
-            "component_name" : "ZOOKEEPER_SERVER",
-            "service_name" : "ZOOKEEPER"
+            "component_name" : "SECONDARY_NAMENODE",
+            "service_name" : "HDFS"
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/ZOOKEEPER_SERVER",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/SECONDARY_NAMENODE",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "4",
-                "component_name" : "ZOOKEEPER_SERVER",
                 "state" : "STARTED",
                 "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "component_name" : "SECONDARY_NAMENODE",
+                "host_name" : "dev.hortonworks.com"
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_SERVER",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/SECONDARY_NAMENODE",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
-                    "component_name" : "ZOOKEEPER_SERVER",
-                    "service_name" : "ZOOKEEPER"
+                    "component_name" : "SECONDARY_NAMENODE",
+                    "service_name" : "HDFS"
                   }
                   }
                 }
                 }
               ]
               ]
@@ -270,111 +240,82 @@
           ]
           ]
         },
         },
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "ZOOKEEPER_CLIENT",
-            "service_name" : "ZOOKEEPER"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/ZOOKEEPER_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "28",
-                "component_name" : "ZOOKEEPER_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_CLIENT",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "ZOOKEEPER_CLIENT",
-                    "service_name" : "ZOOKEEPER"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE",
-      "Services" : {
-        "display_name" : "MapReduce",
-        "description" : "Apache Hadoop Distributed Processing Framework",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": true, \"editable\": false, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "MAPREDUCE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/JOBTRACKER",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/NAMENODE",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
-            "component_name" : "JOBTRACKER",
-            "service_name" : "MAPREDUCE"
+            "component_name" : "NAMENODE",
+            "service_name" : "HDFS"
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/JOBTRACKER",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/NAMENODE",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "3",
-                "component_name" : "JOBTRACKER",
                 "state" : "STARTED",
                 "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "component_name" : "NAMENODE",
+                "host_name" : "dev.hortonworks.com"
               },
               },
               "metrics" : {
               "metrics" : {
                 "rpc" : {
                 "rpc" : {
-                  "rpcAuthorizationSuccesses" : 8,
-                  "SentBytes" : 187411672,
+                  "rpcAuthorizationSuccesses" : 0,
+                  "SentBytes" : 504011,
                   "rpcAuthorizationFailures" : 0,
                   "rpcAuthorizationFailures" : 0,
-                  "ReceivedBytes" : 570755511,
+                  "ReceivedBytes" : 1055599,
                   "NumOpenConnections" : 0,
                   "NumOpenConnections" : 0,
                   "callQueueLen" : 0,
                   "callQueueLen" : 0,
-                  "RpcQueueTime_num_ops" : 1751188,
+                  "RpcQueueTime_num_ops" : 3468,
                   "rpcAuthenticationSuccesses" : 0,
                   "rpcAuthenticationSuccesses" : 0,
-                  "RpcProcessingTime_num_ops" : 1751188,
-                  "RpcProcessingTime_avg_time" : 0.30303030303030304,
+                  "RpcProcessingTime_num_ops" : 3468,
+                  "RpcProcessingTime_avg_time" : 0.0,
                   "rpcAuthenticationFailures" : 0,
                   "rpcAuthenticationFailures" : 0,
-                  "RpcQueueTime_avg_time" : 1.6969696969696975
+                  "RpcQueueTime_avg_time" : 0.6666666666666667
+                },
+                "dfs" : {
+                  "namenode" : {
+                    "AddBlockOps" : 0,
+                    "FileInfoOps" : 0,
+                    "CreateFileOps" : 0,
+                    "GetListingOps" : 0,
+                    "Transactions_num_ops" : 0,
+                    "GetBlockLocations" : 0,
+                    "Syncs_avg_time" : 0.0,
+                    "blockReport_num_ops" : 0,
+                    "Syncs_num_ops" : 0,
+                    "FilesInGetListingOps" : 0,
+                    "Transactions_avg_time" : 0.0,
+                    "FilesCreated" : 0,
+                    "blockReport_avg_time" : 0.0
+                  }
                 },
                 },
                 "rpcdetailed" : {
                 "rpcdetailed" : {
-                  "getProtocolVersion_avg_time" : 0.0,
-                  "getProtocolVersion_num_ops" : 11
+                  "sendHeartbeat_avg_time" : 0.0,
+                  "sendHeartbeat_num_ops" : 3240
                 },
                 },
                 "jvm" : {
                 "jvm" : {
-                  "memHeapCommittedM" : 185.1875,
+                  "memHeapCommittedM" : 960.0,
                   "logFatal" : 0,
                   "logFatal" : 0,
                   "threadsBlocked" : 0,
                   "threadsBlocked" : 0,
-                  "gcCount" : 165,
-                  "threadsWaiting" : 59,
+                  "gcCount" : 1,
+                  "threadsWaiting" : 14,
                   "logWarn" : 0,
                   "logWarn" : 0,
                   "logError" : 0,
                   "logError" : 0,
-                  "memNonHeapCommittedM" : 38.722656,
-                  "memNonHeapUsedM" : 25.408173,
-                  "gcTimeMillis" : 3812,
+                  "memNonHeapCommittedM" : 23.1875,
+                  "memNonHeapUsedM" : 20.247017,
+                  "gcTimeMillis" : 55,
                   "logInfo" : 3,
                   "logInfo" : 3,
                   "threadsNew" : 0,
                   "threadsNew" : 0,
-                  "memHeapUsedM" : 150.10947,
+                  "memHeapUsedM" : 136.56186,
                   "threadsTerminated" : 0,
                   "threadsTerminated" : 0,
-                  "threadsTimedWaiting" : 10,
+                  "threadsTimedWaiting" : 7,
                   "threadsRunnable" : 6
                   "threadsRunnable" : 6
                 },
                 },
                 "metricssystem" : {
                 "metricssystem" : {
                   "dropped_pub_all" : 0,
                   "dropped_pub_all" : 0,
                   "num_sources" : 6,
                   "num_sources" : 6,
-                  "publish_max_time" : 543.0,
-                  "publish_num_ops" : 55219,
+                  "publish_max_time" : 6.0,
+                  "publish_num_ops" : 972,
                   "snapshot_stdev_time" : 0.37796447300922725,
                   "snapshot_stdev_time" : 0.37796447300922725,
-                  "snapshot_num_ops" : 386539,
+                  "snapshot_num_ops" : 6810,
                   "publish_stdev_time" : 0.0,
                   "publish_stdev_time" : 0.0,
                   "num_sinks" : 1,
                   "num_sinks" : 1,
                   "publish_imin_time" : 0.0,
                   "publish_imin_time" : 0.0,
@@ -383,48 +324,18 @@
                   "snapshot_imax_time" : 1.0,
                   "snapshot_imax_time" : 1.0,
                   "publish_avg_time" : 0.0,
                   "publish_avg_time" : 0.0,
                   "publish_min_time" : 0.0,
                   "publish_min_time" : 0.0,
-                  "snapshot_max_time" : 694.0,
+                  "snapshot_max_time" : 10.0,
                   "publish_imax_time" : 1.401298464324817E-45,
                   "publish_imax_time" : 1.401298464324817E-45,
-                  "snapshot_avg_time" : 0.14285714285714285
-                }
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/JOBTRACKER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "JOBTRACKER",
-                    "service_name" : "MAPREDUCE"
-                  }
+                  "snapshot_avg_time" : 0.14285714285714288
                 }
                 }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/MAPREDUCE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "MAPREDUCE_CLIENT",
-            "service_name" : "MAPREDUCE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/MAPREDUCE_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "27",
-                "component_name" : "MAPREDUCE_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/MAPREDUCE_CLIENT",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/NAMENODE",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
-                    "component_name" : "MAPREDUCE_CLIENT",
-                    "service_name" : "MAPREDUCE"
+                    "component_name" : "NAMENODE",
+                    "service_name" : "HDFS"
                   }
                   }
                 }
                 }
               ]
               ]
@@ -432,66 +343,61 @@
           ]
           ]
         },
         },
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/TASKTRACKER",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/DATANODE",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
-            "component_name" : "TASKTRACKER",
-            "service_name" : "MAPREDUCE"
+            "component_name" : "DATANODE",
+            "service_name" : "HDFS"
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/TASKTRACKER",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/DATANODE",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "22",
-                "component_name" : "TASKTRACKER",
                 "state" : "STARTED",
                 "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "component_name" : "DATANODE",
+                "host_name" : "dev.hortonworks.com"
               },
               },
               "metrics" : {
               "metrics" : {
                 "rpc" : {
                 "rpc" : {
-                  "rpcAuthorizationSuccesses" : 14,
-                  "SentBytes" : 11141,
+                  "rpcAuthorizationSuccesses" : 0,
+                  "SentBytes" : 0,
                   "rpcAuthorizationFailures" : 0,
                   "rpcAuthorizationFailures" : 0,
-                  "ReceivedBytes" : 40426,
+                  "ReceivedBytes" : 0,
                   "NumOpenConnections" : 0,
                   "NumOpenConnections" : 0,
                   "callQueueLen" : 0,
                   "callQueueLen" : 0,
-                  "RpcQueueTime_num_ops" : 93,
+                  "RpcQueueTime_num_ops" : 0,
                   "rpcAuthenticationSuccesses" : 0,
                   "rpcAuthenticationSuccesses" : 0,
-                  "RpcProcessingTime_num_ops" : 93,
-                  "RpcProcessingTime_avg_time" : 0.4,
+                  "RpcProcessingTime_num_ops" : 0,
+                  "RpcProcessingTime_avg_time" : 0.0,
                   "rpcAuthenticationFailures" : 0,
                   "rpcAuthenticationFailures" : 0,
                   "RpcQueueTime_avg_time" : 0.0
                   "RpcQueueTime_avg_time" : 0.0
                 },
                 },
-                "rpcdetailed" : {
-                  "getProtocolVersion_avg_time" : 0.0,
-                  "getProtocolVersion_num_ops" : 14
-                },
                 "jvm" : {
                 "jvm" : {
-                  "memHeapCommittedM" : 27.3125,
+                  "memHeapCommittedM" : 45.5625,
                   "logFatal" : 0,
                   "logFatal" : 0,
                   "threadsBlocked" : 0,
                   "threadsBlocked" : 0,
-                  "gcCount" : 46316,
-                  "threadsWaiting" : 15,
+                  "gcCount" : 14,
+                  "threadsWaiting" : 7,
                   "logWarn" : 0,
                   "logWarn" : 0,
                   "logError" : 0,
                   "logError" : 0,
-                  "memNonHeapCommittedM" : 33.75,
-                  "memNonHeapUsedM" : 23.388573,
-                  "gcTimeMillis" : 367178,
+                  "memNonHeapCommittedM" : 23.1875,
+                  "memNonHeapUsedM" : 18.308372,
+                  "gcTimeMillis" : 67,
                   "logInfo" : 3,
                   "logInfo" : 3,
                   "threadsNew" : 0,
                   "threadsNew" : 0,
-                  "memHeapUsedM" : 23.116539,
+                  "memHeapUsedM" : 2.4481506,
                   "threadsTerminated" : 0,
                   "threadsTerminated" : 0,
                   "threadsTimedWaiting" : 7,
                   "threadsTimedWaiting" : 7,
-                  "threadsRunnable" : 6
+                  "threadsRunnable" : 7
                 },
                 },
                 "metricssystem" : {
                 "metricssystem" : {
                   "dropped_pub_all" : 0,
                   "dropped_pub_all" : 0,
-                  "num_sources" : 6,
-                  "publish_max_time" : 808.0,
-                  "publish_num_ops" : 55201,
+                  "num_sources" : 5,
+                  "publish_max_time" : 3.0,
+                  "publish_num_ops" : 974,
                   "snapshot_stdev_time" : 0.0,
                   "snapshot_stdev_time" : 0.0,
-                  "snapshot_num_ops" : 386413,
+                  "snapshot_num_ops" : 5841,
                   "publish_stdev_time" : 0.0,
                   "publish_stdev_time" : 0.0,
                   "num_sinks" : 1,
                   "num_sinks" : 1,
                   "publish_imin_time" : 0.0,
                   "publish_imin_time" : 0.0,
@@ -500,161 +406,14 @@
                   "snapshot_imax_time" : 1.401298464324817E-45,
                   "snapshot_imax_time" : 1.401298464324817E-45,
                   "publish_avg_time" : 0.0,
                   "publish_avg_time" : 0.0,
                   "publish_min_time" : 0.0,
                   "publish_min_time" : 0.0,
-                  "snapshot_max_time" : 656.0,
+                  "snapshot_max_time" : 2.0,
                   "publish_imax_time" : 1.401298464324817E-45,
                   "publish_imax_time" : 1.401298464324817E-45,
                   "snapshot_avg_time" : 0.0
                   "snapshot_avg_time" : 0.0
                 }
                 }
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/TASKTRACKER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "TASKTRACKER",
-                    "service_name" : "MAPREDUCE"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/SQOOP",
-      "Services" : {
-        "display_name" : "Sqoop",
-        "description" : "Tool for transferring bulk data between Apache Hadoop and structured datastores such as relational databases",
-        "attributes" : "{ \"runnable\": false, \"mustInstall\": false, \"editable\": true, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "INSTALLED",
-        "service_name" : "SQOOP"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/SQOOP/components/SQOOP_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "SQOOP_CLIENT",
-            "service_name" : "SQOOP"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/SQOOP_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "31",
-                "component_name" : "SQOOP_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/SQOOP/components/SQOOP_CLIENT",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "SQOOP_CLIENT",
-                    "service_name" : "SQOOP"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/HDFS",
-      "Services" : {
-        "display_name" : "HDFS",
-        "description" : "Apache Hadoop Distributed File System",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": true, \"editable\": false, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "HDFS"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/DATANODE",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "DATANODE",
-            "service_name" : "HDFS"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/DATANODE",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "23",
-                "component_name" : "DATANODE",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "metrics" : {
-                "rpc" : {
-                  "rpcAuthorizationSuccesses" : 4,
-                  "SentBytes" : 1350,
-                  "rpcAuthorizationFailures" : 0,
-                  "ReceivedBytes" : 2006,
-                  "NumOpenConnections" : 0,
-                  "callQueueLen" : 0,
-                  "RpcQueueTime_num_ops" : 7,
-                  "rpcAuthenticationSuccesses" : 0,
-                  "RpcProcessingTime_num_ops" : 7,
-                  "RpcProcessingTime_avg_time" : 1.0,
-                  "rpcAuthenticationFailures" : 0,
-                  "RpcQueueTime_avg_time" : 0.0
-                },
-                "rpcdetailed" : {
-                  "getProtocolVersion_avg_time" : 0.0,
-                  "getProtocolVersion_num_ops" : 2
-                },
-                "jvm" : {
-                  "memHeapCommittedM" : 84.3125,
-                  "logFatal" : 0,
-                  "threadsBlocked" : 0,
-                  "gcCount" : 1229,
-                  "threadsWaiting" : 8,
-                  "logWarn" : 0,
-                  "logError" : 0,
-                  "memNonHeapCommittedM" : 23.375,
-                  "memNonHeapUsedM" : 21.495056,
-                  "gcTimeMillis" : 8111,
-                  "logInfo" : 3,
-                  "threadsNew" : 0,
-                  "memHeapUsedM" : 28.507965,
-                  "threadsTerminated" : 0,
-                  "threadsTimedWaiting" : 8,
-                  "threadsRunnable" : 12
-                },
-                "metricssystem" : {
-                  "dropped_pub_all" : 0,
-                  "num_sources" : 5,
-                  "publish_max_time" : 501.0,
-                  "publish_num_ops" : 55260,
-                  "snapshot_stdev_time" : 0.408248290463863,
-                  "snapshot_num_ops" : 331565,
-                  "publish_stdev_time" : 0.0,
-                  "num_sinks" : 1,
-                  "publish_imin_time" : 1.0,
-                  "snapshot_min_time" : 0.0,
-                  "snapshot_imin_time" : 0.0,
-                  "snapshot_imax_time" : 1.0,
-                  "publish_avg_time" : 1.0,
-                  "publish_min_time" : 0.0,
-                  "snapshot_max_time" : 585.0,
-                  "publish_imax_time" : 1.0,
-                  "snapshot_avg_time" : 0.16666666666666669
-                }
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HDFS/components/DATANODE",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/DATANODE",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
                     "component_name" : "DATANODE",
                     "component_name" : "DATANODE",
@@ -666,7 +425,7 @@
           ]
           ]
         },
         },
         {
         {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/HDFS_CLIENT",
+          "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/HDFS_CLIENT",
           "ServiceComponentInfo" : {
           "ServiceComponentInfo" : {
             "cluster_name" : "mycluster",
             "cluster_name" : "mycluster",
             "component_name" : "HDFS_CLIENT",
             "component_name" : "HDFS_CLIENT",
@@ -674,17 +433,16 @@
           },
           },
           "host_components" : [
           "host_components" : [
             {
             {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HDFS_CLIENT",
+              "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/hosts/dev.hortonworks.com/host_components/HDFS_CLIENT",
               "HostRoles" : {
               "HostRoles" : {
                 "cluster_name" : "mycluster",
                 "cluster_name" : "mycluster",
-                "role_id" : "26",
-                "component_name" : "HDFS_CLIENT",
                 "state" : "INSTALLED",
                 "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
+                "component_name" : "HDFS_CLIENT",
+                "host_name" : "dev.hortonworks.com"
               },
               },
               "component" : [
               "component" : [
                 {
                 {
-                  "href" : "http://ambari/clusters/mycluster/services/HDFS/components/HDFS_CLIENT",
+                  "href" : "http://dev.hortonworks.com:8080/api/clusters/mycluster/services/HDFS/components/HDFS_CLIENT",
                   "ServiceComponentInfo" : {
                   "ServiceComponentInfo" : {
                     "cluster_name" : "mycluster",
                     "cluster_name" : "mycluster",
                     "component_name" : "HDFS_CLIENT",
                     "component_name" : "HDFS_CLIENT",
@@ -694,468 +452,6 @@
               ]
               ]
             }
             }
           ]
           ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/SNAMENODE",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "SNAMENODE",
-            "service_name" : "HDFS"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/SNAMENODE",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "2",
-                "component_name" : "SNAMENODE",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HDFS/components/SNAMENODE",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "SNAMENODE",
-                    "service_name" : "HDFS"
-                  }
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/NAMENODE",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "NAMENODE",
-            "service_name" : "HDFS"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/NAMENODE",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "1",
-                "component_name" : "NAMENODE",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "metrics" : {
-                "rpc" : {
-                  "rpcAuthorizationSuccesses" : 56734,
-                  "SentBytes" : 71919973,
-                  "rpcAuthorizationFailures" : 0,
-                  "ReceivedBytes" : 82615006,
-                  "NumOpenConnections" : 0,
-                  "callQueueLen" : 0,
-                  "RpcQueueTime_num_ops" : 407816,
-                  "rpcAuthenticationSuccesses" : 0,
-                  "RpcProcessingTime_num_ops" : 407816,
-                  "RpcProcessingTime_avg_time" : 0.0,
-                  "rpcAuthenticationFailures" : 0,
-                  "RpcQueueTime_avg_time" : 0.0
-                },
-                "dfs" : {
-                  "namenode" : {
-                    "AddBlockOps" : 178,
-                    "FileInfoOps" : 91688,
-                    "CreateFileOps" : 181,
-                    "GetListingOps" : 73730,
-                    "Transactions_num_ops" : 973,
-                    "GetBlockLocations" : 45,
-                    "Syncs_avg_time" : 4.0,
-                    "blockReport_num_ops" : 137,
-                    "Syncs_num_ops" : 587,
-                    "FilesInGetListingOps" : 188175,
-                    "Transactions_avg_time" : 0.0,
-                    "FilesCreated" : 314,
-                    "blockReport_avg_time" : 1.0
-                  }
-                },
-                "rpcdetailed" : {
-                  "addBlock_avg_time" : 0.0,
-                  "rollFsImage_num_ops" : 26,
-                  "getListing_num_ops" : 82658,
-                  "renewLease_avg_time" : 0.0,
-                  "sendHeartbeat_num_ops" : 183761,
-                  "create_avg_time" : 2.0,
-                  "fsync_num_ops" : 8,
-                  "blockReport_num_ops" : 154,
-                  "create_num_ops" : 181,
-                  "getEditLogSize_num_ops" : 1837,
-                  "rollEditLog_num_ops" : 26,
-                  "rollFsImage_avg_time" : 237.0,
-                  "getBlockLocations_num_ops" : 45,
-                  "getFileInfo_avg_time" : 0.0,
-                  "addBlock_num_ops" : 178,
-                  "getProtocolVersion_avg_time" : 0.0,
-                  "getListing_avg_time" : 0.33333333333333337,
-                  "rollEditLog_avg_time" : 36.0,
-                  "getBlockLocations_avg_time" : 0.0,
-                  "blockReceived_avg_time" : 0.0,
-                  "renewLease_num_ops" : 18186,
-                  "getEditLogSize_avg_time" : 0.0,
-                  "getFileInfo_num_ops" : 101504,
-                  "sendHeartbeat_avg_time" : 0.0,
-                  "complete_avg_time" : 12.0,
-                  "fsync_avg_time" : 0.0,
-                  "complete_num_ops" : 183,
-                  "blockReceived_num_ops" : 177,
-                  "getProtocolVersion_num_ops" : 18437,
-                  "blockReport_avg_time" : 1.0
-                },
-                "jvm" : {
-                  "memHeapCommittedM" : 432.0625,
-                  "logFatal" : 0,
-                  "threadsBlocked" : 0,
-                  "gcCount" : 194029,
-                  "threadsWaiting" : 104,
-                  "logWarn" : 0,
-                  "logError" : 0,
-                  "memNonHeapCommittedM" : 36.847656,
-                  "memNonHeapUsedM" : 23.048737,
-                  "gcTimeMillis" : 218543395,
-                  "logInfo" : 3,
-                  "threadsNew" : 0,
-                  "memHeapUsedM" : 93.0164,
-                  "threadsTerminated" : 0,
-                  "threadsTimedWaiting" : 8,
-                  "threadsRunnable" : 10
-                },
-                "metricssystem" : {
-                  "dropped_pub_all" : 0,
-                  "num_sources" : 6,
-                  "publish_max_time" : 2320.0,
-                  "publish_num_ops" : 55266,
-                  "snapshot_stdev_time" : 0.37796447300922725,
-                  "snapshot_num_ops" : 386868,
-                  "publish_stdev_time" : 0.0,
-                  "num_sinks" : 1,
-                  "publish_imin_time" : 0.0,
-                  "snapshot_min_time" : 0.0,
-                  "snapshot_imin_time" : 0.0,
-                  "snapshot_imax_time" : 1.0,
-                  "publish_avg_time" : 0.0,
-                  "publish_min_time" : 0.0,
-                  "snapshot_max_time" : 2770.0,
-                  "publish_imax_time" : 1.401298464324817E-45,
-                  "snapshot_avg_time" : 0.14285714285714288
-                }
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HDFS/components/NAMENODE",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "NAMENODE",
-                    "service_name" : "HDFS"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/NAGIOS",
-      "Services" : {
-        "display_name" : "Nagios",
-        "description" : "Nagios-based Monitoring for HDP",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": true, \"editable\": false, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "NAGIOS"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/NAGIOS/components/NAGIOS_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "NAGIOS_SERVER",
-            "service_name" : "NAGIOS"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/NAGIOS_SERVER",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "10",
-                "component_name" : "NAGIOS_SERVER",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/NAGIOS/components/NAGIOS_SERVER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "NAGIOS_SERVER",
-                    "service_name" : "NAGIOS"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/HIVE",
-      "Services" : {
-        "display_name" : "Hive/HCatalog",
-        "description" : "Hive - Data Warehouse system for Apache Hadoop, HCatalog - Table and Storage Management service for data created using Apache Hadoop",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": false, \"editable\": true, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "HIVE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "HIVE_SERVER",
-            "service_name" : "HIVE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HIVE_SERVER",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "7",
-                "component_name" : "HIVE_SERVER",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_SERVER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "HIVE_SERVER",
-                    "service_name" : "HIVE"
-                  }
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "HIVE_CLIENT",
-            "service_name" : "HIVE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HIVE_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "33",
-                "component_name" : "HIVE_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_CLIENT",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "HIVE_CLIENT",
-                    "service_name" : "HIVE"
-                  }
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_MYSQL",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "HIVE_MYSQL",
-            "service_name" : "HIVE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/HIVE_MYSQL",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "35",
-                "component_name" : "HIVE_MYSQL",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_MYSQL",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "HIVE_MYSQL",
-                    "service_name" : "HIVE"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/GANGLIA",
-      "Services" : {
-        "display_name" : "Ganglia",
-        "description" : "Ganglia-based Metrics Collection for HDP",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": true, \"editable\": false, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "GANGLIA"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/GANGLIA/components/GANGLIA_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "GANGLIA_SERVER",
-            "service_name" : "GANGLIA"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/GANGLIA_SERVER",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "9",
-                "component_name" : "GANGLIA_SERVER",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/GANGLIA/components/GANGLIA_SERVER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "GANGLIA_SERVER",
-                    "service_name" : "GANGLIA"
-                  }
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/GANGLIA/components/GANGLIA_MONITOR",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "GANGLIA_MONITOR",
-            "service_name" : "GANGLIA"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/GANGLIA_MONITOR",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "25",
-                "component_name" : "GANGLIA_MONITOR",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/GANGLIA/components/GANGLIA_MONITOR",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "GANGLIA_MONITOR",
-                    "service_name" : "GANGLIA"
-                  }
-                }
-              ]
-            }
-          ]
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/OOZIE",
-      "Services" : {
-        "display_name" : "Oozie",
-        "description" : "Workflow/Coordination system to manage Apache Hadoop jobs",
-        "attributes" : "{ \"runnable\": true, \"mustInstall\": false, \"editable\": true, \"noDisplay\": false }"
-      },
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "state" : "STARTED",
-        "service_name" : "OOZIE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/OOZIE/components/OOZIE_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "OOZIE_SERVER",
-            "service_name" : "OOZIE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/OOZIE_SERVER",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "6",
-                "component_name" : "OOZIE_SERVER",
-                "state" : "STARTED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/OOZIE/components/OOZIE_SERVER",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "OOZIE_SERVER",
-                    "service_name" : "OOZIE"
-                  }
-                }
-              ]
-            }
-          ]
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/OOZIE/components/OOZIE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "component_name" : "OOZIE_CLIENT",
-            "service_name" : "OOZIE"
-          },
-          "host_components" : [
-            {
-              "href" : "http://ambari/clusters/mycluster/hosts/ip-10-38-5-128.ec2.internal/host_components/OOZIE_CLIENT",
-              "HostRoles" : {
-                "cluster_name" : "mycluster",
-                "role_id" : "32",
-                "component_name" : "OOZIE_CLIENT",
-                "state" : "INSTALLED",
-                "host_name" : "ip-10-38-5-128.ec2.internal"
-              },
-              "component" : [
-                {
-                  "href" : "http://ambari/clusters/mycluster/services/OOZIE/components/OOZIE_CLIENT",
-                  "ServiceComponentInfo" : {
-                    "cluster_name" : "mycluster",
-                    "component_name" : "OOZIE_CLIENT",
-                    "service_name" : "OOZIE"
-                  }
-                }
-              ]
-            }
-          ]
         }
         }
       ]
       ]
     }
     }

+ 0 - 320
ambari-web/app/assets/data/dashboard/servicesHealth.json

@@ -1,320 +0,0 @@
-{
-  "href" : "http://ambari/clusters/mycluster/services?ServiceInfo/service_name!=MISCELLANEOUS&ServiceInfo/service_name!=DASHBOARD&fields=components/ServiceComponentInfo/state",
-  "items" : [
-    {
-      "href" : "http://ambari/clusters/mycluster/services/NAGIOS",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "NAGIOS"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/NAGIOS/components/NAGIOS_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "NAGIOS_SERVER",
-            "service_name" : "NAGIOS"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/TEMPLETON",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "TEMPLETON"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/TEMPLETON/components/TEMPLETON_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "TEMPLETON_CLIENT",
-            "service_name" : "TEMPLETON"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/TEMPLETON/components/TEMPLETON_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "TEMPLETON_SERVER",
-            "service_name" : "TEMPLETON"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/HDFS",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "HDFS"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/DATANODE",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "DATANODE",
-            "service_name" : "HDFS"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/NAMENODE",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "NAMENODE",
-            "service_name" : "HDFS"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/SNAMENODE",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "SNAMENODE",
-            "service_name" : "HDFS"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HDFS/components/HDFS_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "HDFS_CLIENT",
-            "service_name" : "HDFS"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/SQOOP",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "SQOOP"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/SQOOP/components/SQOOP_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "SQOOP_CLIENT",
-            "service_name" : "SQOOP"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/PIG",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "PIG"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/PIG/components/PIG_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "PIG_CLIENT",
-            "service_name" : "PIG"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/HBASE",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "HBASE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_REGIONSERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "HBASE_REGIONSERVER",
-            "service_name" : "HBASE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_MASTER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "HBASE_MASTER",
-            "service_name" : "HBASE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HBASE/components/HBASE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "HBASE_CLIENT",
-            "service_name" : "HBASE"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "ZOOKEEPER"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "ZOOKEEPER_CLIENT",
-            "service_name" : "ZOOKEEPER"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/ZOOKEEPER/components/ZOOKEEPER_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "ZOOKEEPER_SERVER",
-            "service_name" : "ZOOKEEPER"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "MAPREDUCE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/MAPREDUCE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "MAPREDUCE_CLIENT",
-            "service_name" : "MAPREDUCE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/JOBTRACKER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "JOBTRACKER",
-            "service_name" : "MAPREDUCE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/MAPREDUCE/components/TASKTRACKER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "TASKTRACKER",
-            "service_name" : "MAPREDUCE"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/HIVE",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "HIVE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_MYSQL",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "HIVE_MYSQL",
-            "service_name" : "HIVE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "HIVE_CLIENT",
-            "service_name" : "HIVE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/HIVE/components/HIVE_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "HIVE_SERVER",
-            "service_name" : "HIVE"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/GANGLIA",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "GANGLIA"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/GANGLIA/components/GANGLIA_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "GANGLIA_SERVER",
-            "service_name" : "GANGLIA"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/GANGLIA/components/GANGLIA_MONITOR",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "GANGLIA_MONITOR",
-            "service_name" : "GANGLIA"
-          }
-        }
-      ]
-    },
-    {
-      "href" : "http://ambari/clusters/mycluster/services/OOZIE",
-      "ServiceInfo" : {
-        "cluster_name" : "mycluster",
-        "service_name" : "OOZIE"
-      },
-      "components" : [
-        {
-          "href" : "http://ambari/clusters/mycluster/services/OOZIE/components/OOZIE_CLIENT",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "INSTALLED",
-            "component_name" : "OOZIE_CLIENT",
-            "service_name" : "OOZIE"
-          }
-        },
-        {
-          "href" : "http://ambari/clusters/mycluster/services/OOZIE/components/OOZIE_SERVER",
-          "ServiceComponentInfo" : {
-            "cluster_name" : "mycluster",
-            "state" : "STARTED",
-            "component_name" : "OOZIE_SERVER",
-            "service_name" : "OOZIE"
-          }
-        }
-      ]
-    }
-  ]
-}

+ 126 - 0
ambari-web/app/assets/data/hosts/hosts.json

@@ -0,0 +1,126 @@
+{
+  "href" : "http://localhost:8080/api/hosts?fields=*",
+  "items" : [
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host01",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.1"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host02",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.2"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host03",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.3"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host04",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.4"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host05",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.5"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host06",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.6"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host07",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.7"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host08",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.8"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host09",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.9"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host10",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.10"
+      }
+    },
+    {
+      "href" : "http://localhost:8080/api/hosts/host1",
+      "Hosts" : {
+        "cpu_count" : 1,
+        "total_mem" : 2055208,
+        "os_arch" : "x86_64",
+        "host_name" : "host11",
+        "os_type" : "centos6",
+        "ip" : "10.0.2.11"
+      }
+    }
+  ]
+}

+ 12 - 1
ambari-web/app/controllers/installer.js

@@ -77,9 +77,20 @@ App.InstallerController = Em.Controller.extend({
    * @param completed
    * @param completed
    */
    */
   currentStep: function () {
   currentStep: function () {
-    return App.get('router').getInstallerCurrentStep();
+    return App.get('router').getWizardCurrentStep('installer');
   }.property(),
   }.property(),
 
 
+  /**
+   * Set current step to new value.
+   * Method moved from App.router.setInstallerCurrentStep
+   * @param currentStep
+   * @param completed
+   */
+  setCurrentStep: function (currentStep, completed) {
+    App.db.setWizardCurrentStep('installer', currentStep, completed);
+    this.set('currentStep', currentStep);
+  },
+
   clusters: null,
   clusters: null,
 
 
   isStep1: function () {
   isStep1: function () {

+ 65 - 13
ambari-web/app/controllers/main.js

@@ -21,11 +21,14 @@ require('models/background_operation');
 
 
 App.MainController = Em.Controller.extend({
 App.MainController = Em.Controller.extend({
   name: 'mainController',
   name: 'mainController',
-  backgroundOperations: null,
+  backgroundOperations: [],
+  backgroundOperationsCount : 0,
+  backgroundOperationsUrl : '',
   intervalId: false,
   intervalId: false,
-  updateOperationsInterval: 8000,
+  updateOperationsInterval: 6000,
 
 
   startLoadOperationsPeriodically: function() {
   startLoadOperationsPeriodically: function() {
+    this.loadBackgroundOperations();
     this.intervalId = setInterval(this.loadBackgroundOperations, this.get('updateOperationsInterval'));
     this.intervalId = setInterval(this.loadBackgroundOperations, this.get('updateOperationsInterval'));
   },
   },
   stopLoadOperationsPeriodically:function () {
   stopLoadOperationsPeriodically:function () {
@@ -36,19 +39,68 @@ App.MainController = Em.Controller.extend({
   },
   },
   loadBackgroundOperations: function(){
   loadBackgroundOperations: function(){
     var self = App.router.get('mainController');
     var self = App.router.get('mainController');
-    jQuery.getJSON('data/hosts/background_operations/bg_operations.json',
-      function (data) {
-        var backgroundOperations = self.get('backgroundOperations');
-        if(!backgroundOperations || self.get('backgroundOperationsCount') >= 6)
-          self.set('backgroundOperations', data);
-        else backgroundOperations.tasks.pushObjects(data['tasks'])
-      }
-    )
+
+    var url = self.get('backgroundOperationsUrl');
+    if(!url){
+      //cache url, not to execute <code>getClusterName</code> everytime
+      url = (App.testMode) ?
+        '/data/background_operations/list_on_start.json' :
+        '/api/clusters/' + App.router.getClusterName() + '/requests/?fields=tasks/*&tasks/Tasks/status!=COMPLETED';
+      self.set('backgroundOperationsUrl', url);
+    }
+
+    $.ajax({
+      type: "GET",
+      url: url,
+      dataType: 'json',
+      timeout: 5000,
+      success: function (data) {
+        self.updateBackgroundOperations(data);
+      },
+
+      error: function (request, ajaxOptions, error) {
+        //do something
+      },
+
+      statusCode: require('data/statusCodes')
+    });
   },
   },
 
 
-  backgroundOperationsCount: function() {
-    return this.get('backgroundOperations.tasks.length');
-  }.property('backgroundOperations.tasks.length'),
+  /**
+   * Add new operations to <code>this.backgroundOperations</code> variable
+   * @param data json loaded from server
+   */
+  updateBackgroundOperations : function(data){
+    var runningTasks = [];
+    data.items.forEach(function (item) {
+      item.tasks.forEach(function (task) {
+        if (task.Tasks.status == 'QUEUED') {
+          runningTasks.push(task.Tasks);
+        }
+      });
+    });
+
+    var currentTasks = this.get('backgroundOperations');
+
+    runningTasks.forEach(function(item){
+      var task = currentTasks.findProperty('id', item.id);
+      if(task){
+        currentTasks[currentTasks.indexOf(task)] = item;
+      } else {
+        currentTasks.pushObject(item);
+      }
+    });
+
+    for(var i = currentTasks.length-1; i>=0; i--){
+      var isTaskFinished = !runningTasks.someProperty('id', currentTasks[i].id);
+      if(isTaskFinished){
+        currentTasks.removeAt(i);
+      }
+    }
+
+    this.set('backgroundOperationsCount', currentTasks.length);
+
+  },
 
 
   showBackgroundOperationsPopup: function(){
   showBackgroundOperationsPopup: function(){
     App.ModalPopup.show({
     App.ModalPopup.show({

+ 7 - 10
ambari-web/app/controllers/main/apps_controller.js

@@ -68,13 +68,16 @@ App.MainAppsController = Em.ArrayController.extend({
     });
     });
     return r;
     return r;
   },
   },
+  lastStarClicked: -1,
   /**
   /**
    * Click on star on table row
    * Click on star on table row
    * @return {Boolean} false for prevent default event handler
    * @return {Boolean} false for prevent default event handler
    */
    */
-  starClick: function() {
-    event.srcElement.classList.toggle('stared');
-    var id = parseInt(event.srcElement.parentNode.childNodes[1].innerText);
+  starClick: function(event) {
+    event.target.classList.toggle('stared');
+    var cell = event.target.parentNode.parentNode;
+    var row = cell.parentNode;
+    var id = parseInt(jQuery(event.target).parent().children(1).text());
     if (!this.issetStaredRun(id)) {
     if (!this.issetStaredRun(id)) {
       this.get('staredRuns').push(this.getRunById(id));
       this.get('staredRuns').push(this.getRunById(id));
     }
     }
@@ -85,13 +88,7 @@ App.MainAppsController = Em.ArrayController.extend({
       }
       }
     }
     }
     this.set('staredRunsLength', this.get('staredRuns').length);
     this.set('staredRunsLength', this.get('staredRuns').length);
+    this.set('lastStarClicked', id);
     return false;
     return false;
-  },
-  /**
-   * Flush all starred runs
-   */
-  clearStars: function() {
-    this.set('staredRuns', []);
-    this.set('staredRunsLength', 0);
   }
   }
 })
 })

+ 25 - 2
ambari-web/app/controllers/main/host.js

@@ -35,6 +35,27 @@ App.MainHostController = Em.ArrayController.extend(App.Pagination, {
   rangeStart:0,
   rangeStart:0,
   allChecked:false,
   allChecked:false,
   selectedHostsIds:[],
   selectedHostsIds:[],
+  selectedRack:null,
+  assignHostsToRack:function () {
+    var selectedRack = this.get('selectedRack');
+    var sureMessage = this.t('hosts.assignToRack.sure');
+    var hostsIds = this.get('selectedHostsIds');
+
+    var hostString = hostsIds.length + " " + this.t(hostsIds.length > 1 ? "host.plural" : "host.singular");
+
+    if (selectedRack.constructor == 'App.Cluster' && hostsIds.length
+      && confirm(sureMessage.format(hostString, selectedRack.get('clusterName')))) {
+      this.get('content').forEach(function (host) {
+        if (host.get('isChecked')) {
+          host.set('cluster', selectedRack);
+          host.set('isChecked', false);
+        }
+      })
+      this.set('selectedHostsIds', []);
+    }
+
+  }.observes('selectedRack'),
+
   sortingAsc:true,
   sortingAsc:true,
   isSort:false,
   isSort:false,
   sortClass:function () {
   sortClass:function () {
@@ -83,12 +104,14 @@ App.MainHostController = Em.ArrayController.extend(App.Pagination, {
   onHostChecked:function (host) {
   onHostChecked:function (host) {
     var selected = this.get('selectedHostsIds');
     var selected = this.get('selectedHostsIds');
     host.set('isChecked', !host.get('isChecked'));
     host.set('isChecked', !host.get('isChecked'));
-    if (host.get('isChecked')) selected.push(host.get('id'));
-    else {
+    if (host.get('isChecked')) {
+      selected.push(host.get('id'));
+    } else {
       var index = selected.indexOf(host.get('id'));
       var index = selected.indexOf(host.get('id'));
       if (index != -1) selected.splice(index, 1);
       if (index != -1) selected.splice(index, 1);
     }
     }
     this.set('isDisabled', selected.length == 0);
     this.set('isDisabled', selected.length == 0);
+    this.propertyDidChange('selectedHostsIds');
   },
   },
 
 
   changeSelectedHosts:function () {
   changeSelectedHosts:function () {

+ 143 - 2
ambari-web/app/controllers/main/service/info/configs.js

@@ -17,8 +17,149 @@
  */
  */
 
 
 var App = require('app');
 var App = require('app');
+require('controllers/wizard/slave_component_groups_controller');
 
 
 App.MainServiceInfoConfigsController = Em.Controller.extend({
 App.MainServiceInfoConfigsController = Em.Controller.extend({
   name: 'mainServiceInfoConfigsController',
   name: 'mainServiceInfoConfigsController',
-  content: 'Configs'
-})
+  stepConfigs: [], //contains all field properties that are viewed in this service
+  selectedService: null,
+  serviceConfigs: require('data/service_configs'),
+
+  isSubmitDisabled: function () {
+    return !this.stepConfigs.everyProperty('errorCount', 0);
+  }.property('stepConfigs.@each.errorCount'),
+
+  slaveComponentHosts : function(){
+    console.log('slaveComponentHosts');
+    console.log(App.db.getSlaveComponentHosts());
+    return App.db.getSlaveComponentHosts();
+  }.property('content'),
+
+  clearStep: function () {
+    this.get('stepConfigs').clear();
+  },
+
+  serviceConfigProperties: function() {
+    console.log('serviceConfigProperties');
+    console.log(App.db.getServiceConfigProperties());
+    return App.db.getServiceConfigProperties();
+  }.property('content'),
+
+  /**
+   * On load function
+   */
+  loadStep: function () {
+    console.log("TRACE: Loading configure for service");
+
+    this.clearStep();
+    this.renderServiceConfigs(this.serviceConfigs);
+
+    var storedServices = this.get('serviceConfigProperties');
+    if (storedServices) {
+      var configs = new Ember.Set();
+
+      // for all services`
+      this.get('stepConfigs').forEach(function (_content) {
+        //for all components
+        _content.get('configs').forEach(function (_config) {
+
+          var componentVal = storedServices.findProperty('name', _config.get('name'));
+          //if we have config for specified component
+          if(componentVal){
+
+            //set it
+            _config.set('value', componentVal.value)
+          }
+
+        }, this);
+      }, this);
+    }
+
+    console.log('---------------------------------------');
+    console.log(this.get('stepConfigs'));
+
+  },
+
+  /**
+   * Render configs for active services
+   * @param serviceConfigs
+   */
+  renderServiceConfigs: function (serviceConfigs) {
+    serviceConfigs.forEach(function (_serviceConfig) {
+      var serviceConfig = App.ServiceConfig.create({
+        serviceName: _serviceConfig.serviceName,
+        displayName: _serviceConfig.displayName,
+        configCategories: _serviceConfig.configCategories,
+        configs: []
+      });
+
+      if (this.get('content.serviceName') && this.get('content.serviceName').toUpperCase() === serviceConfig.serviceName) {
+        this.loadComponentConfigs(_serviceConfig, serviceConfig);
+
+        console.log('pushing ' + serviceConfig.serviceName);
+        this.get('stepConfigs').pushObject(serviceConfig);
+
+      } else {
+        console.log('skipping ' + serviceConfig.serviceName);
+      }
+    }, this);
+
+    this.set('selectedService', this.get('stepConfigs').objectAt(0));
+  },
+
+  /**
+   * Load child components to service config object
+   * @param _componentConfig
+   * @param componentConfig
+   */
+  loadComponentConfigs: function (_componentConfig, componentConfig) {
+    _componentConfig.configs.forEach(function (_serviceConfigProperty) {
+      var serviceConfigProperty = App.ServiceConfigProperty.create(_serviceConfigProperty);
+      serviceConfigProperty.serviceConfig = componentConfig;
+      serviceConfigProperty.initialValue();
+      componentConfig.configs.pushObject(serviceConfigProperty);
+      serviceConfigProperty.validate();
+    }, this);
+  },
+
+  /**
+   * Save config properties
+   */
+  saveServiceConfigProperties: function () {
+    var serviceConfigProperties = [];
+    this.get('stepConfigs').forEach(function (_content) {
+      _content.get('configs').forEach(function (_configProperties) {
+        var configProperty = {
+          name: _configProperties.get('name'),
+          value: _configProperties.get('value'),
+          service: _configProperties.get('serviceName')
+        };
+        serviceConfigProperties.push(configProperty);
+      }, this);
+
+    }, this);
+
+    App.db.setServiceConfigProperties(serviceConfigProperties);
+    alert('Data saved successfully');
+//    this.set('content.serviceConfigProperties', serviceConfigProperties);
+  }
+});
+
+App.MainServiceSlaveComponentGroupsController = App.SlaveComponentGroupsController.extend({
+  name: 'mainServiceSlaveComponentGroupsController',
+  contentBinding: 'App.router.mainServiceInfoConfigsController.slaveComponentHosts',
+  serviceBinding: 'App.router.mainServiceInfoConfigsController.selectedService',
+
+  selectedComponentName: function () {
+    switch (App.router.get('mainServiceInfoConfigsController.selectedService.serviceName')) {
+      case 'HDFS':
+        return 'DATANODE';
+      case 'MAPREDUCE':
+        return 'TASKTRACKER';
+      case 'HBASE':
+        return 'HBASE_REGIONSERVER';
+      default:
+        return null;
+    }
+  }.property('App.router.mainServiceInfoConfigsController.selectedService')
+});

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

@@ -24,7 +24,7 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
     var serviceId = this.get('content.serviceName');
     var serviceId = this.get('content.serviceName');
     if (serviceId) {
     if (serviceId) {
       return this.get('allAlerts').filter(function (item) {
       return this.get('allAlerts').filter(function (item) {
-        return item.get('serviceType').toLowerCase() == serviceId;
+        return item.get('serviceType') && item.get('serviceType').toLowerCase() == serviceId;
       });
       });
     }
     }
     return [];
     return [];

+ 61 - 0
ambari-web/app/controllers/main/service/item.js

@@ -69,7 +69,45 @@ App.MainServiceItemController = Em.Controller.extend({
 
 
     return operation;
     return operation;
   },
   },
+  /**
+   * Send specific command to server
+   * @param url
+   * @param data Object to send
+   */
+  sendCommandToServer : function(url, postData){
+    var url =  (App.testMode) ?
+      '/data/wizard/deploy/poll_1.json' : //content is the same as ours
+      '/api/clusters/' + App.router.getClusterName() + url; //'/services/' + this.get('content.serviceName').toUpperCase();
+
+    var method = App.testMode ? 'GET' : 'PUT';
+
+    $.ajax({
+      type: method,
+      url: url,
+      data: JSON.stringify(postData),
+      dataType: 'json',
+      timeout: 5000,
+      success: function (data) {
+        //do something
+      },
+
+      error: function (request, ajaxOptions, error) {
+        //do something
+      },
+
+      statusCode: require('data/statusCodes')
+    });
+  },
+
+  /**
+   * On click callback for <code>start service</code> button
+   * @param event
+   */
   startService: function (event) {
   startService: function (event) {
+    if($(event.target).hasClass('disabled')){
+      return;
+    }
+
     var self = this;
     var self = this;
     App.ModalPopup.show({
     App.ModalPopup.show({
       header: Em.I18n.t('services.service.confirmation.header'),
       header: Em.I18n.t('services.service.confirmation.header'),
@@ -78,6 +116,13 @@ App.MainServiceItemController = Em.Controller.extend({
       secondary: 'No',
       secondary: 'No',
       onPrimary: function() {
       onPrimary: function() {
         self.content.set('workStatus', true);
         self.content.set('workStatus', true);
+
+        self.sendCommandToServer('/services/' + self.get('content.serviceName').toUpperCase(),{
+          ServiceInfo:{
+            state: 'STARTED'
+          }
+        });
+
         var newOperation = self.createBackgroundOperation('Service', 'Start');
         var newOperation = self.createBackgroundOperation('Service', 'Start');
         newOperation.detail = "Another detail info";
         newOperation.detail = "Another detail info";
         self.addBackgroundOperation(newOperation);
         self.addBackgroundOperation(newOperation);
@@ -88,7 +133,16 @@ App.MainServiceItemController = Em.Controller.extend({
       }
       }
     });
     });
   },
   },
+
+  /**
+   * On click callback for <code>stop service</code> button
+   * @param event
+   */
   stopService: function (event) {
   stopService: function (event) {
+    if($(event.target).hasClass('disabled')){
+      return;
+    }
+
     var self = this;
     var self = this;
     App.ModalPopup.show({
     App.ModalPopup.show({
       header: Em.I18n.t('services.service.confirmation.header'),
       header: Em.I18n.t('services.service.confirmation.header'),
@@ -97,6 +151,13 @@ App.MainServiceItemController = Em.Controller.extend({
       secondary: 'No',
       secondary: 'No',
       onPrimary: function() {
       onPrimary: function() {
         self.content.set('workStatus', false);
         self.content.set('workStatus', false);
+
+        self.sendCommandToServer('/services/' + self.get('content.serviceName').toUpperCase(),{
+          ServiceInfo:{
+            state: 'INSTALLED'
+          }
+        });
+
         var newOperation = self.createBackgroundOperation('Service', 'Stop');
         var newOperation = self.createBackgroundOperation('Service', 'Stop');
         newOperation.detail = "Another detail info";
         newOperation.detail = "Another detail info";
         self.addBackgroundOperation(newOperation);
         self.addBackgroundOperation(newOperation);

+ 11 - 10
ambari-web/app/controllers/wizard/step10_controller.js

@@ -141,33 +141,34 @@ App.WizardStep10Controller = Em.Controller.extend({
 
 
     console.log('STEP10 master components:  ' + JSON.stringify(components));
     console.log('STEP10 master components:  ' + JSON.stringify(components));
     components.forEach(function (_component) {
     components.forEach(function (_component) {
-      switch (_component.component) {
+      var component = Ember.Object.create(_component);
+      switch (component.component) {
         case 'NAMENODE':
         case 'NAMENODE':
-          this.loadNn(_component);
+          this.loadNn(component);
           break;
           break;
         case 'SECONDARY_NAMENODE':
         case 'SECONDARY_NAMENODE':
-          this.loadSnn(_component);
+          this.loadSnn(component);
           break;
           break;
         case 'JOBTRACKER' :
         case 'JOBTRACKER' :
-          this.loadJt(_component);
+          this.loadJt(component);
           break;
           break;
         case 'ZOOKEEPER_SERVER' :
         case 'ZOOKEEPER_SERVER' :
-          this.loadZk(_component);
+          this.loadZk(component);
           break;
           break;
         case 'HBASE_MASTER':
         case 'HBASE_MASTER':
-          this.loadHb(_component);
+          this.loadHb(component);
           break;
           break;
         case 'HIVE_SERVER':
         case 'HIVE_SERVER':
-          this.loadHiveServer(_component);
+          this.loadHiveServer(component);
           break;
           break;
         case 'OOZIE_SERVER':
         case 'OOZIE_SERVER':
-          this.loadOozieServer(_component);
+          this.loadOozieServer(component);
           break;
           break;
         case 'GANGLIA_SERVER':
         case 'GANGLIA_SERVER':
-          this.loadGanglia(_component)
+          this.loadGanglia(component)
           break;
           break;
         case 'NAGIOS_SERVER':
         case 'NAGIOS_SERVER':
-          this.loadNagios(_component);
+          this.loadNagios(component);
           break;
           break;
       }
       }
     }, this);
     }, this);

+ 6 - 1
ambari-web/app/controllers/wizard/step2_controller.js

@@ -92,7 +92,12 @@ App.WizardStep2Controller = Em.Controller.extend({
   }.property('sshKey', 'manualInstall', 'hasSubmitted'),
   }.property('sshKey', 'manualInstall', 'hasSubmitted'),
 
 
   localRepoError: function () {
   localRepoError: function () {
-    if (this.get('hasSubmitted') && this.get('localRepo') && this.get('localRepoPath').trim() === '') {
+    if (
+       // (typeof this.get('localRepoPath') === 'undefined') ||
+        !(/^([-a-z0-9._\/]|%[0-9a-f]{2})*$/i.test(this.get('localRepoPath')) ) ||
+        (this.get('hasSubmitted') && this.get('localRepo') && this.get('localRepoPath').trim() === '' )
+       )
+    {
       return Em.I18n.t('installer.step2.localRepo.error.required');
       return Em.I18n.t('installer.step2.localRepo.error.required');
     }
     }
     return null;
     return null;

+ 8 - 8
ambari-web/app/controllers/wizard/step8_controller.js

@@ -451,6 +451,7 @@ App.WizardStep8Controller = Em.Controller.extend({
       async: false,
       async: false,
       //accepts: 'text',
       //accepts: 'text',
       dataType: 'text',
       dataType: 'text',
+      data: '{"Clusters": {"version" : "HDP-0.1"}}',
       timeout: 5000,
       timeout: 5000,
       success: function (data) {
       success: function (data) {
         var jsonData = jQuery.parseJSON(data);
         var jsonData = jQuery.parseJSON(data);
@@ -511,10 +512,7 @@ App.WizardStep8Controller = Em.Controller.extend({
       var components = serviceComponents.filterProperty('service_name', _service);
       var components = serviceComponents.filterProperty('service_name', _service);
       components.forEach(function (_component) {
       components.forEach(function (_component) {
         console.log("value of component is: " + _component.component_name);
         console.log("value of component is: " + _component.component_name);
-        // TODO: Skipping CLIENT components as we have issues on the server side for integration purposes
-        if (!_component.component_name.match(/CLIENT$/)) {
-          this.createComponent(_service, _component.component_name);
-        }
+        this.createComponent(_service, _component.component_name);
       }, this);
       }, this);
     }, this);
     }, this);
   },
   },
@@ -582,6 +580,7 @@ App.WizardStep8Controller = Em.Controller.extend({
 
 
     var masterHosts = this.get('content.masterComponentHosts');
     var masterHosts = this.get('content.masterComponentHosts');
     var slaveHosts = this.get('content.slaveComponentHosts');
     var slaveHosts = this.get('content.slaveComponentHosts');
+    var clients = this.get('content.clients');
     var allHosts = this.get('content.hostsInfo');
     var allHosts = this.get('content.hostsInfo');
 
 
     masterHosts.forEach(function (_masterHost) {
     masterHosts.forEach(function (_masterHost) {
@@ -601,8 +600,7 @@ App.WizardStep8Controller = Em.Controller.extend({
           slaveObj.component = _client.component_name;
           slaveObj.component = _client.component_name;
           _slaveHosts.hosts.forEach(function (_slaveHost) {
           _slaveHosts.hosts.forEach(function (_slaveHost) {
             slaveObj.hostName = _slaveHost.hostname;
             slaveObj.hostName = _slaveHost.hostname;
-            // TODO: Skip creation of clients for integration purposes
-            // this.createHostComponent(slaveObj);
+            this.createHostComponent(slaveObj);
           }, this);
           }, this);
         }, this);
         }, this);
       }
       }
@@ -650,10 +648,12 @@ App.WizardStep8Controller = Em.Controller.extend({
       this.createConfigSite(this.createMrSiteObj('MAPREDUCE'));
       this.createConfigSite(this.createMrSiteObj('MAPREDUCE'));
     }
     }
     if (selectedServices.someProperty('serviceName', 'HBASE')) {
     if (selectedServices.someProperty('serviceName', 'HBASE')) {
-      this.createConfigSite(this.createHbaseSiteObj('HBASE'));
+      // TODO
+      // this.createConfigSite(this.createHbaseSiteObj('HBASE'));
     }
     }
     if (selectedServices.someProperty('serviceName', 'HIVE')) {
     if (selectedServices.someProperty('serviceName', 'HIVE')) {
-      this.createConfigSite(this.createHiveSiteObj('HIVE'));
+      // TODO
+      // this.createConfigSite(this.createHiveSiteObj('HIVE'));
     }
     }
   },
   },
 
 

+ 12 - 12
ambari-web/app/controllers/wizard/step9_controller.js

@@ -116,33 +116,33 @@ App.WizardStep9Controller = Em.Controller.extend({
           case 'PENDING':
           case 'PENDING':
             return 'Preparing to install ' + task.role;
             return 'Preparing to install ' + task.role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is Queued for installation';
+            return task.role + ' is queued for installation';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
             return 'Installing ' + task.role;
             return 'Installing ' + task.role;
           case 'COMPLETED' :
           case 'COMPLETED' :
             return 'Successfully installed ' + task.role;
             return 'Successfully installed ' + task.role;
           case 'FAILED':
           case 'FAILED':
-            return 'Faliure in installing ' + task.role;
+            return 'Failed to install ' + task.role;
         }
         }
       case 'UNINSTALL':
       case 'UNINSTALL':
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
             return 'Preparing to uninstall ' + task.role;
             return 'Preparing to uninstall ' + task.role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is Queued for uninstallation';
+            return task.role + ' is queued for uninstallation';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
-            return 'Unnstalling ' + task.role;
+            return 'Uninstalling ' + task.role;
           case 'COMPLETED' :
           case 'COMPLETED' :
             return 'Successfully uninstalled ' + task.role;
             return 'Successfully uninstalled ' + task.role;
           case 'FAILED':
           case 'FAILED':
-            return 'Faliure in uninstalling ' + task.role;
+            return 'Failed to uninstall ' + task.role;
         }
         }
       case 'START' :
       case 'START' :
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
             return 'Preparing to start ' + task.role;
             return 'Preparing to start ' + task.role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is Queued for starting';
+            return task.role + ' is queued for starting';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
             return 'Starting ' + task.role;
             return 'Starting ' + task.role;
           case 'COMPLETED' :
           case 'COMPLETED' :
@@ -153,13 +153,13 @@ App.WizardStep9Controller = Em.Controller.extend({
       case 'STOP' :
       case 'STOP' :
         switch (task.status) {
         switch (task.status) {
           case 'PENDING':
           case 'PENDING':
-            return 'Preparing to stop ' + role;
+            return 'Preparing to stop ' + task.role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is Queued for stopping';
+            return task.role + ' is queued for stopping';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
             return 'Stopping ' + task.role;
             return 'Stopping ' + task.role;
           case 'COMPLETED' :
           case 'COMPLETED' :
-            return role + ' stoped successfully';
+            return role + ' stopped successfully';
           case 'FAILED':
           case 'FAILED':
             return role + ' failed to stop';
             return role + ' failed to stop';
         }
         }
@@ -168,7 +168,7 @@ App.WizardStep9Controller = Em.Controller.extend({
           case 'PENDING':
           case 'PENDING':
             return 'Preparing to execute' + task.role;
             return 'Preparing to execute' + task.role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is Queued for execution';
+            return task.role + ' is queued for execution';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
             return 'Execution of ' + task.role + ' in progress';
             return 'Execution of ' + task.role + ' in progress';
           case 'COMPLETED' :
           case 'COMPLETED' :
@@ -181,7 +181,7 @@ App.WizardStep9Controller = Em.Controller.extend({
           case 'PENDING':
           case 'PENDING':
             return 'Preparing to abort ' + task.role;
             return 'Preparing to abort ' + task.role;
           case 'QUEUED' :
           case 'QUEUED' :
-            return task.role + ' is Queued for Aborting';
+            return task.role + ' is queued for aborting';
           case 'IN_PROGRESS':
           case 'IN_PROGRESS':
             return 'Aborting ' + task.role;
             return 'Aborting ' + task.role;
           case 'COMPLETED' :
           case 'COMPLETED' :
@@ -500,7 +500,7 @@ App.WizardStep9Controller = Em.Controller.extend({
   getUrl: function () {
   getUrl: function () {
     var clusterName = this.get('content.cluster.name');
     var clusterName = this.get('content.cluster.name');
     var requestId = App.db.getClusterStatus().requestId;
     var requestId = App.db.getClusterStatus().requestId;
-    var url = '/api/clusters/' + clusterName + '/requests/' + requestId;
+    var url = '/api/clusters/' + clusterName + '/requests/' + requestId + '?fields=tasks/*';
     console.log("URL for step9 is: " + url);
     console.log("URL for step9 is: " + url);
     return url;
     return url;
   },
   },

+ 1 - 1
ambari-web/app/data/service_components.js

@@ -45,7 +45,7 @@ module.exports = new Ember.Set([
   {
   {
     service_name: 'HDFS',
     service_name: 'HDFS',
     component_name: 'HDFS_CLIENT',
     component_name: 'HDFS_CLIENT',
-    display_name: 'Hadoop Client',
+    display_name: 'HDFS Client',
     isMaster: false,
     isMaster: false,
     isClient: true,
     isClient: true,
     description: 'Client component for HDFS'
     description: 'Client component for HDFS'

+ 7 - 2
ambari-web/app/initialize.js

@@ -19,8 +19,8 @@
 
 
 window.App = require('app');
 window.App = require('app');
 
 
-//App.testMode = true;
-App.testMode = false;
+App.testMode = true;
+//App.testMode = false;
 
 
 require('messages');
 require('messages');
 require('utils/data_table');
 require('utils/data_table');
@@ -31,6 +31,11 @@ require('controllers');
 require('views');
 require('views');
 require('router');
 require('router');
 
 
+require('mappers/server_data_mapper');
+require('mappers/services_mapper');
+
+require('utils/http_client');
+
 App.initialize();
 App.initialize();
 
 
 console.log('after initialize');
 console.log('after initialize');

+ 35 - 0
ambari-web/app/mappers/alerts_mapper.js

@@ -0,0 +1,35 @@
+/**
+ * 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.
+ */
+
+//todo: refactor it
+App.alertsMapper = App.ServerDataMapper.create({
+  map: function (json) {
+    if (json.alerts) {
+      $.each(json.alerts, function (i, _alert) {
+        var alert = App.store.createRecord(App.Alert, {
+          alertId: _alert.service_description,
+          title: _alert.service_description,
+          serviceType: _alert.service_type,
+          date: new Date(_alert.last_hard_state_change * 1000),
+          status: _alert.current_state,
+          message: _alert.plugin_output
+        });
+      });
+    }
+  }
+});

+ 38 - 0
ambari-web/app/mappers/hosts_mapper.js

@@ -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.
+ */
+
+//todo: refactor it
+App.hostsMapper = App.ServerDataMapper.create({
+  map: function (json) {
+    if (json.items) {
+      json.items.forEach(function (data) {
+        if (data.Hosts) {
+          App.store.createRecord(App.Host, {
+            id: data.Hosts.host_name,
+            hostName: data.Hosts.host_name,
+            cpuCount: data.Hosts.cpu_count,
+            totalMem: data.Hosts.total_mem,
+            osArch: data.Hosts.os_arch,
+            osType: data.Hosts.os_type,
+            ip: data.Hosts.ip
+          });
+        }
+      });
+    }
+  }
+});

+ 45 - 0
ambari-web/app/mappers/server_data_mapper.js

@@ -0,0 +1,45 @@
+/**
+ * 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.ServerDataMapper = Em.Object.extend({
+  jsonKey: false,
+  map: function (json) {
+    if (json) {
+      var model = this.get('model');
+      var jsonKey = this.get('jsonKey');
+
+      if (jsonKey && json[jsonKey]) { // if data come as { hdfs: {...} }
+        json = json[jsonKey];
+      }
+
+      $.each(json, function (field, value) {
+        model.set(field, value);
+      })
+    }
+  }
+});
+
+
+App.QuickDataMapper = App.ServerDataMapper.extend({
+  config : {},
+  map : function(json){
+    //todo: move code here
+  }
+});

+ 116 - 0
ambari-web/app/mappers/services_mapper.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.
+ */
+/*
+App.servicesMapper = App.ServerDataMapper.create({
+  map: function (json) {
+    if (json.items) {
+      json.items.forEach(function (data) {
+        if (data.ServiceInfo) {
+          var service = App.store.createRecord(App.Service, {
+            id: data.ServiceInfo.service_name.toLowerCase(),
+            serviceName: data.ServiceInfo.service_name.toLowerCase()
+          });
+
+          if (data.components) {
+            var components = service.get('components');
+            $.each(data.components, function (i, _component) {
+              if (_component.ServiceComponentInfo) {
+                var component = App.store.createRecord(App.ServiceComponent, {
+                  id: _component.ServiceComponentInfo.component_name,
+                  componentName: _component.ServiceComponentInfo.component_name
+                });
+                components.pushObject(component);
+
+                if (_component.host_components) {
+                  var hostComponents = component.get('hostComponents');
+                  $.each(_component.host_components, function (j, _hostComponent) {
+                    var _hostRoles = _hostComponent.HostRoles;
+                    var hostComponent = App.store.createRecord(App.HostComponent, {
+                      hostComponentId: _hostRoles.component_name + ":" + _hostRoles.host_name,
+                      host: App.Host.find(_hostRoles.host_name),
+                      hostName: _hostRoles.host_name,
+                      state: _hostRoles.state
+                    });
+                    hostComponents.pushObject(hostComponent);
+                  });
+                }
+              }
+            });
+          }
+        }
+      });
+    }
+  }
+});
+*/
+App.servicesMapper = App.QuickDataMapper.create({
+  config : {
+    id : 'ServiceInfo.service_name',
+    service_name : 'ServiceInfo.service_name',
+    components_key : 'components',
+    components : {
+        id : 'ServiceComponentInfo.component_name',
+        component_name : 'ServiceComponentInfo.component_name',
+        //service_id : 'ServiceComponentInfo.service_name',
+        service_name : 'ServiceComponentInfo.service_name',
+        state: 'host_components[0].HostRoles.state',
+        host_name: 'host_components[0].HostRoles.host_name'
+      }
+  },
+  map:function(json){
+    if(json.items){
+      var result = [];
+      json.items.forEach(function(item){
+        result.push(this.parseIt(item, this.config));
+      }, this)
+
+      App.store.loadMany(App.Service1, result);
+    }
+  },
+  parseIt : function(data, config){
+    var result = {};
+    for(var i in config){
+      if(i.substr(-4) !== '_key' && typeof config[i] == 'string'){
+        result[i] = this.getJsonProperty(data, config[i]);
+      } else if(typeof config[i] == 'object'){
+        result[i] = [];
+        var _data = data[config[i+'_key']];
+        var l = _data.length;
+        for(var index = 0; index<l; index++){
+          result[i].push(this.parseIt(_data[index], config[i]));
+        }
+      }
+    }
+    return result;
+  },
+  getJsonProperty:function(json, path){
+    var pathArr = path.split('.');
+    var current = json;
+    while(pathArr.length){
+      if(pathArr[0].substr(-1) == ']'){
+        var index = parseInt(pathArr[0].substr(-2,1));
+        var attr = pathArr[0].substr(0, pathArr[0].length-3);
+        current = current[attr][index];
+      } else {
+        current = current[pathArr[0]];
+      }
+      pathArr.splice(0,1);
+    }
+    return current;
+  }
+});

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

@@ -26,16 +26,16 @@ Em.I18n.translations = {
   'login.loginButton': 'Sign in',
   'login.loginButton': 'Sign in',
   'login.error': 'Invalid username/password combination.',
   'login.error': 'Invalid username/password combination.',
 
 
-  'services.nagios.description': 'Nagios desc',
-  'services.ganglia.description': 'Ganglia desc',
-  'services.hdfs.description': 'HDFS desc',
-  'services.mapreduce.description': 'MapReduce desc',
-  'services.sqoop.description': 'Sqoop desc',
-  'services.pig.description': 'Pig desc',
-  'services.hive.description': 'Hive/HCat desc',
-  'services.oozie.description': 'Oozie desc',
+  'services.nagios.description': 'Nagios Monitoring and Alerting system',
+  'services.ganglia.description': 'Ganglia Metrics Collection system',
+  'services.hdfs.description': 'Apache Hadoop Distributed File System',
+  'services.mapreduce.description': 'Apache Hadoop Distributed Processing Framework',
+  'services.sqoop.description': 'Tool for transferring bulk data between Apache Hadoop and structured data stores such as relational databases',
+  'services.pig.description': 'Scripting platform for analyzing large datasets',
+  'services.hive.description': 'Data warehouse system for ad-hoc queries & analysis of large datasets and table & storage management service',
+  'services.oozie.description': 'System for workflow coordination and execution of Apache Hadoop jobs',
   'services.zookeeper.description': 'ZooKeeper desc',
   'services.zookeeper.description': 'ZooKeeper desc',
-  'services.hbase.description': 'HBase desc',
+  'services.hbase.description': 'Non-relational distributed database and centralized service for configuration management & synchronization',
 
 
   'topnav.help.href': 'http://incubator.apache.org/ambari/install.html',
   'topnav.help.href': 'http://incubator.apache.org/ambari/install.html',
 
 
@@ -57,7 +57,7 @@ Em.I18n.translations = {
   'installer.step2.targetHosts.info': 'Enter a list of host names, one per line',
   'installer.step2.targetHosts.info': 'Enter a list of host names, one per line',
   'installer.step2.hostPattern.tooltip.title': 'Pattern Expressions',
   'installer.step2.hostPattern.tooltip.title': 'Pattern Expressions',
   'installer.step2.hostPattern.tooltip.content': 'You can use pattern expressions to specify a number of target hosts.  Explain brackets.',
   'installer.step2.hostPattern.tooltip.content': 'You can use pattern expressions to specify a number of target hosts.  Explain brackets.',
-  'installer.step2.hostName.error.required': 'Host Names cannot be left empty',
+  'installer.step2.hostName.error.required': 'You must specify at least one host name',
   'installer.step2.hostName.error.notRequired': 'Host Names will be ignored if not using SSH to automatically configure hosts',
   'installer.step2.hostName.error.notRequired': 'Host Names will be ignored if not using SSH to automatically configure hosts',
   'installer.step2.hostName.error.invalid': 'Invalid Host Name(s) - cannot start or end with a hyphen',
   'installer.step2.hostName.error.invalid': 'Invalid Host Name(s) - cannot start or end with a hyphen',
   'installer.step2.sshKey': 'Host Connectivity Information',
   'installer.step2.sshKey': 'Host Connectivity Information',
@@ -69,7 +69,7 @@ Em.I18n.translations = {
     'Ambari Agent on each host in order for the wizard to perform the necessary configurations and software installs.',
     'Ambari Agent on each host in order for the wizard to perform the necessary configurations and software installs.',
   'installer.step2.advancedOption': 'Advanced Options',
   'installer.step2.advancedOption': 'Advanced Options',
   'installer.step2.repoConf': 'Software Repository Configuration File Path',
   'installer.step2.repoConf': 'Software Repository Configuration File Path',
-  'installer.step2.localRepo.header': 'Software repository',
+  'installer.step2.localRepo.header': 'Software Repository',
   'installer.step2.localRepo.label': 'Use a local software repository',
   'installer.step2.localRepo.label': 'Use a local software repository',
   'installer.step2.localRepo.error.required': 'Local repository file path is required',
   'installer.step2.localRepo.error.required': 'Local repository file path is required',
   'installer.step2.localRepo.info': 'The repository configuration file should be installed on each host in your cluster. ' +
   'installer.step2.localRepo.info': 'The repository configuration file should be installed on each host in your cluster. ' +
@@ -121,9 +121,9 @@ Em.I18n.translations = {
   'installer.step9.body': 'Wait to complete the cluster installation. Installing, Starting and Testing selected services',
   'installer.step9.body': 'Wait to complete the cluster installation. Installing, Starting and Testing selected services',
   'installer.step9.status.success': 'Successfully installed the cluster',
   'installer.step9.status.success': 'Successfully installed the cluster',
   'installer.step9.status.failed': 'Failure in installation',
   'installer.step9.status.failed': 'Failure in installation',
-  'installer.step9.host.status.success': 'success',
-  'installer.step9.host.status.warning': 'tolerable failures encountered',
-  'installer.step9.host.status.failed': 'failures encountered',
+  'installer.step9.host.status.success': 'Success',
+  'installer.step9.host.status.warning': 'Warnings encountered',
+  'installer.step9.host.status.failed': 'Failures encountered',
   'installer.step9.hostLog.popup.header': 'Tasks executed on ',
   'installer.step9.hostLog.popup.header': 'Tasks executed on ',
 
 
   'installer.step10.header': 'Summary',
   'installer.step10.header': 'Summary',
@@ -230,6 +230,9 @@ Em.I18n.translations = {
 
 
   'services.add.header': 'Add Service Wizard',
   'services.add.header': 'Add Service Wizard',
 
 
+  'host.singular': 'host',
+  'host.plural': 'hosts',
+
   'hosts.host.start.popup.header': 'Confirmation',
   'hosts.host.start.popup.header': 'Confirmation',
   'hosts.host.stop.popup.header': 'Confirmation',
   'hosts.host.stop.popup.header': 'Confirmation',
   'hosts.host.start.popup.body': 'Are you sure?',
   'hosts.host.start.popup.body': 'Are you sure?',
@@ -243,6 +246,10 @@ Em.I18n.translations = {
   'hosts.cant.do.popup.header': 'Operation not allowed',
   'hosts.cant.do.popup.header': 'Operation not allowed',
   'hosts.cant.do.popup.masterList.body': 'You cannot delete this host because it is hosting following master services: {0}.',
   'hosts.cant.do.popup.masterList.body': 'You cannot delete this host because it is hosting following master services: {0}.',
   'hosts.cant.do.popup.workingList.body': 'You cannot delete this host because following slave services are not fully stopped or decommissioned: {0}.',
   'hosts.cant.do.popup.workingList.body': 'You cannot delete this host because following slave services are not fully stopped or decommissioned: {0}.',
+  'hosts.assignToRack.sure': 'Sure you want to assign {0} to {1}?',
+  'hosts.add.header': 'Add Host Wizard',
+  'hosts.add.step2.warning': 'Hosts are already part of the cluster and will be ignored',
+  'hosts.assignRack': 'Assign Rack',
 
 
   'charts.horizon.chart.showText': 'show',
   'charts.horizon.chart.showText': 'show',
   'charts.horizon.chart.hideText': 'hide',
   'charts.horizon.chart.hideText': 'hide',
@@ -264,9 +271,6 @@ Em.I18n.translations = {
   'metric.more.network': 'Network',
   'metric.more.network': 'Network',
   'metric.more.process': 'Process',
   'metric.more.process': 'Process',
 
 
-  'hosts.add.header': 'Add Host Wizard',
-  'hosts.add.step2.warning': 'Hosts are already part of the cluster and will be ignored',
-
   'dashboard.services': 'Services',
   'dashboard.services': 'Services',
   'dashboard.services.hosts': 'Hosts',
   'dashboard.services.hosts': 'Hosts',
   'dashboard.services.uptime': '{0} days {1} hrs {2} mins',
   'dashboard.services.uptime': '{0} days {1} hrs {2} mins',
@@ -306,6 +310,7 @@ Em.I18n.translations = {
   'dashboard.services.hbase.regionServersSummary': '{0} live / {1} total',
   'dashboard.services.hbase.regionServersSummary': '{0} live / {1} total',
   'dashboard.services.hbase.chart.label': 'Request Count',
   'dashboard.services.hbase.chart.label': 'Request Count',
 
 
+
   'timeRange.presets.1hour': '1h',
   'timeRange.presets.1hour': '1h',
   'timeRange.presets.12hour': '12h',
   'timeRange.presets.12hour': '12h',
   'timeRange.presets.1day': '1d',
   'timeRange.presets.1day': '1d',

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

@@ -35,4 +35,5 @@ require('models/rack');
 require('models/job');
 require('models/job');
 require('models/run');
 require('models/run');
 require('models/app');
 require('models/app');
-require('models/background_operation');
+require('models/background_operation');
+require('models/protoRelations');

+ 8 - 104
ambari-web/app/models/alert.js

@@ -28,13 +28,13 @@ App.AlertStatus = {
  * which comes back from NAGIOS server.
  * which comes back from NAGIOS server.
  */
  */
 App.Alert = DS.Model.extend({
 App.Alert = DS.Model.extend({
-  title: DS.attr('string', {key: 'service_description'}),
-  serviceType: DS.attr('string', {key: 'service_type'}),
-  date: DS.attr('date', {key: 'last_hard_state_change'}),
-  status: DS.attr('string', {key: 'current_state'}),
-  message: DS.attr('string', {key: 'plugin_output'}),
-  primaryKey: 'last_hard_state_change',
-  alerts: DS.hasMany('App.Alert'),
+  alertId: DS.attr('string'),
+  title: DS.attr('string'),
+  serviceType: DS.attr('string'),
+  date: DS.attr('date'),
+  status: DS.attr('string'),
+  message: DS.attr('string'),
+  primaryKey: 'alertId',
 
 
   /**
   /**
    * Used to show correct icon in UI
    * Used to show correct icon in UI
@@ -113,104 +113,8 @@ App.Alert = DS.Model.extend({
  * RESTAdapter will contact server.
  * RESTAdapter will contact server.
  */
  */
 App.Alert.reopenClass({
 App.Alert.reopenClass({
-  url: "http://nagiosserver/hdp/nagios/nagios_alerts.php?q1=alerts&alert_type=all"
+//  url: "http://nagiosserver/hdp/nagios/nagios_alerts.php?q1=alerts&alert_type=all"
 });
 });
 
 
 App.Alert.FIXTURES = [
 App.Alert.FIXTURES = [
-  {
-    id: 1,
-    title: 'Corrupt/Missing Block',
-    service_id: 1,
-    date: 'August 29, 2012 17:00',
-    status: 'corrupt',
-    message: 'message'
-  },
-  {
-    id: 2,
-    title: 'Corrupt/Missing Block',
-    service_id: 1,
-    date: 'August 30, 2012 17:00',
-    status: 'ok',
-    message: 'message'
-  },
-  {
-    id: 3,
-    title: 'Corrupt/Missing Block',
-    service_id: 2,
-    date: 'August 29, 2012 17:00',
-    status: 'corrupt',
-    message: 'message'
-  },
-  {
-    id: 4,
-    title: 'Corrupt/Missing Block',
-    service_id: 2,
-    date: 'August 30, 2012 17:00',
-    status: 'ok',
-    message: 'message'
-  },
-  {
-    id: 5,
-    title: 'Corrupt/Missing Block',
-    service_id: 3,
-    date: 'August 29, 2012 17:00',
-    status: 'corrupt',
-    message: 'message'
-  },
-  {
-    id: 6,
-    title: 'Corrupt/Missing Block',
-    service_id: 3,
-    date: 'August 30, 2012 17:00',
-    status: 'ok',
-    message: 'message'
-  },
-  {
-    id: 7,
-    title: 'Corrupt/Missing Block',
-    service_id: 4,
-    date: 'August 29, 2012 17:00',
-    status: 'corrupt',
-    message: 'message'
-  },
-  {
-    id: 8,
-    title: 'Corrupt/Missing Block',
-    service_id: 4,
-    date: 'August 30, 2012 17:00',
-    status: 'ok',
-    message: 'message'
-  },
-  {
-    id: 9,
-    title: 'Corrupt/Missing Block',
-    service_id: 5,
-    date: 'August 29, 2012 17:00',
-    status: 'corrupt',
-    message: 'message'
-  },
-  {
-    id: 10,
-    title: 'Corrupt/Missing Block',
-    service_id: 5,
-    date: 'August 30, 2012 17:00',
-    status: 'ok',
-    message: 'message'
-  },
-  {
-    id: 11,
-    title: 'Corrupt/Missing Block',
-    service_id: 6,
-    date: 'August 29, 2012 17:00',
-    status: 'corrupt',
-    message: 'message'
-  },
-  {
-    id: 12,
-    title: 'Corrupt/Missing Block',
-    service_id: 6,
-    date: 'August 30, 2012 17:00',
-    status: 'ok',
-    message: 'message'
-  }
 ];
 ];

+ 1 - 7
ambari-web/app/models/app.js

@@ -25,13 +25,7 @@ App.App = DS.Model.extend({
   numJobsTotal: DS.attr('number'),
   numJobsTotal: DS.attr('number'),
   userName: DS.attr('string'),
   userName: DS.attr('string'),
   executionTime: DS.attr('string'),
   executionTime: DS.attr('string'),
-  runs: DS.hasMany('App.Run'),
-  isRunning: function () {
-    if (!this.get('isLoaded')) {
-      return false;
-    }
-    return this.get('runs').someProperty('isRunning', true);
-  }.property('runs.@each.isRunning')
+  runs: DS.hasMany('App.Run')
 });
 });
 
 
 App.App.FIXTURES = [
 App.App.FIXTURES = [

File diff suppressed because it is too large
+ 16 - 1
ambari-web/app/models/job.js


+ 155 - 0
ambari-web/app/models/protoRelations.js

@@ -0,0 +1,155 @@
+/**
+ * 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.Service1 = DS.Model.extend({
+  //primaryKey : 'serviceName',
+  serviceName: DS.attr('string'),
+  description: DS.attr('string'),
+  components: DS.hasMany('App.Service1Component', { embedded: true }),
+
+  displayName: function() {
+    switch (this.get('serviceName').toLowerCase()) {
+      case 'hdfs':
+        return 'HDFS';
+      case 'mapreduce':
+        return 'MapReduce';
+      case 'hbase':
+        return 'HBase';
+      case 'oozie':
+        return 'Oozie';
+      case 'hive':
+        return 'Hive/HCatalog';
+      case 'zookeeper':
+        return 'ZooKeeper';
+      case 'pig':
+        return 'Pig';
+      case 'sqoop':
+        return 'Sqoop';
+      case 'templeton':
+        return 'Templeton';
+      case 'ganglia':
+        return 'Ganglia';
+      case 'nagios':
+        return 'Nagios';
+    }
+    return this.get('serviceName');
+  }.property('serviceName')
+});
+
+App.Service1.Health = {
+  live:"LIVE",
+  dead:"DEAD",
+  start:"STARTING",
+  stop:"STOPPING"
+};
+
+App.Service1Component = DS.Model.extend({
+  componentName: DS.attr('string'),
+  hostComponents: DS.hasMany('App.HostComponent1'),
+  service: DS.belongsTo('App.Service1'),
+  state : DS.attr('string'),
+  host_name : DS.attr('string'),
+
+  displayName: function() {
+    switch (this.get('componentName')) {
+      case 'NAMENODE':
+        return 'NameNode';
+      case 'SNAMENODE':
+        return 'SNameNode';
+      case 'DATANODE':
+        return 'DataNode';
+      case 'HDFS_CLIENT':
+        return 'HDFS Client';
+      case 'JOBTRACKER':
+        return 'JobTracker';
+      case 'TASKTRACKER':
+        return 'TaskTracker';
+      case 'MAPREDUCE_CLIENT':
+        return 'MapReduce Client';
+      case 'ZOOKEEPER_SERVER':
+        return 'ZooKeeper Server';
+      case 'ZOOKEEPER_CLIENT':
+        return 'ZooKeeper Client';
+      case 'HIVE_SERVER':
+        return 'Hive Server';
+      case 'HIVE_CLIENT':
+        return 'Hive Client';
+      case 'HIVE_MYSQL':
+        return 'Hive MySQL';
+      case 'HBASE_MASTER':
+        return 'HBase Master';
+      case 'HBASE_REGIONSERVER':
+        return 'RegionServer';
+      case 'HBASE_CLIENT':
+        return 'HBase Client';
+      case 'PIG_CLIENT':
+        return 'Pig Client';
+      case 'SQOOP_CLIENT':
+        return 'Sqoop Client';
+      case 'TEMPLETON_SERVER':
+        return 'Templeton Server';
+      case 'TEMPLETON_CLIENT':
+        return 'Templeton Client';
+      case 'OOZIE_SERVER':
+        return 'Oozie Server';
+      case 'OOZIE_CLIENT':
+        return 'Oozie Client';
+      case 'NAGIOS_SERVER':
+        return 'Nagios Server';
+      case 'GANGLIA_SERVER':
+        return 'Ganglia Collector';
+      case 'GANGLIA_MONITOR':
+        return 'Ganglia Monitor';
+    }
+    return this.get('componentName');
+  }.property('componentName'),
+
+  isMaster: function() {
+    switch (this.get('componentName')) {
+      case 'NAMENODE':
+      case 'SNAMENODE':
+      case 'JOBTRACKER':
+      case 'ZOOKEEPER_SERVER':
+      case 'HIVE_SERVER':
+      case 'HBASE_MASTER':
+      case 'NAGIOS_SERVER':
+      case 'GANGLIA_SERVER':
+      case 'OOZIE_SERVER':
+      case 'TEMPLETON_SERVER':
+        return true;
+      default:
+        return false;
+    }
+    return this.get('componentName');
+  }.property('componentName')
+});
+
+App.HostComponent1 = DS.Model.extend({
+  primaryKey: 'hostComponentId',
+  hostComponentId: DS.attr('string'), // component_name + host_name
+  state: DS.attr('string'),
+  host: DS.belongsTo('App.Host'),
+  hostName: DS.attr('string')
+});
+
+// A hack to allow App.<model>.find() with the DS.FixtureAdapter
+App.Service1.FIXTURES = [];
+App.Service1Component.FIXTURES = [];
+App.HostComponent1.FIXTURES = [];

+ 61 - 48
ambari-web/app/models/run.js

@@ -19,6 +19,7 @@
 
 
 var App = require('app');
 var App = require('app');
 var date = require('utils/date');
 var date = require('utils/date');
+var misc = require('utils/misc');
 
 
 App.Run = DS.Model.extend({
 App.Run = DS.Model.extend({
   runId:DS.attr('string'),
   runId:DS.attr('string'),
@@ -27,22 +28,77 @@ App.Run = DS.Model.extend({
   userName:DS.attr('string'),
   userName:DS.attr('string'),
   startTime:DS.attr('string'),
   startTime:DS.attr('string'),
   lastUpdateTime:DS.attr('string'),
   lastUpdateTime:DS.attr('string'),
-  numJobsTotal:DS.attr('number'),
-  numJobsCompleted:DS.attr('number'),
-  input: DS.attr('number'),
-  output: DS.attr('number'),
   appId:DS.attr('number'),
   appId:DS.attr('number'),
   jobs:DS.hasMany('App.Job'),
   jobs:DS.hasMany('App.Job'),
+  /**
+   * Number of comleted jobs.
+   * Field calculates dynamicaly using <code>jobs</code> property
+   */
+  numJobsCompleted: function() {
+    return this.get('jobs').filterProperty('status', 'RUNNING').length;
+  }.property('jobs.@each.status'),
   duration: function() {
   duration: function() {
     return date.dateFormatInterval(parseInt((parseInt(this.get('lastUpdateTime')) - parseInt(this.get('startTime')))/1000));
     return date.dateFormatInterval(parseInt((parseInt(this.get('lastUpdateTime')) - parseInt(this.get('startTime')))/1000));
   }.property('lastUpdateTime', 'startTime'),
   }.property('lastUpdateTime', 'startTime'),
+  /**
+   * Status of running jobs
+   * Field calculates dynamicaly using <code>jobs</code> property
+   */
   isRunning: function () {
   isRunning: function () {
     if (!this.get('isLoaded')) {
     if (!this.get('isLoaded')) {
       return false;
       return false;
     }
     }
-    console.log('RUN: ' + this.get('id')+' '+this.get('jobs').someProperty('status', 'RUNNING'));
     return this.get('jobs').someProperty('status', 'RUNNING');
     return this.get('jobs').someProperty('status', 'RUNNING');
   }.property('jobs.@each.status'),
   }.property('jobs.@each.status'),
+  /**
+   * Sum of input bandwidth for all jobs
+   * Field calculates dynamicaly using <code>jobs</code> property
+   */
+  input: function () {
+    var sum = 0;
+    this.get('jobs').forEach(
+        function(item){
+          sum += item.get('input') || 0;
+        });
+    return sum;
+  }.property('jobs.@each.input'),
+  /**
+   *  Sum of input bandwidth for all jobs with appropriate measure
+   * Field calculates dynamicaly using <code>jobs</code> property
+   */
+  inputFormatted: function () {
+    var input = this.get('input');
+    input = misc.formatBandwidth(input);
+    return input;
+  }.property('input'),
+  /**
+   * Sum of output bandwidth for all jobs
+   * Field calculates dynamicaly using <code>jobs</code> property
+   */
+  output: function () {
+    var sum = 0;
+    this.get('jobs').forEach(
+        function(item){
+          sum += item.get('output') || 0;
+        });
+    return sum;
+  }.property('jobs.@each.output'),
+  /**
+   *  Sum of output bandwidth for all jobs with appropriate measure
+   *  Field calculates dynamicaly using <code>jobs</code> property
+   */
+  outputFormatted: function () {
+    var output = this.get('output');
+    output = misc.formatBandwidth(output);
+    return output;
+  }.property('output'),
+  /**
+   * Number of jobs on this run
+   * Field calculates dynamicaly using <code>jobs</code> property
+   */
+  numJobsTotal: function() {
+    return this.get('jobs.content').length;
+  }.property('jobs'),
   lastUpdateTimeFormatted: function() {
   lastUpdateTimeFormatted: function() {
     return date.dateFormat(this.get('lastUpdateTime'));
     return date.dateFormat(this.get('lastUpdateTime'));
   }.property('lastUpdateTime')
   }.property('lastUpdateTime')
@@ -57,10 +113,6 @@ App.Run.FIXTURES = [
     user_name:'user3',
     user_name:'user3',
     start_time:1347539541501,
     start_time:1347539541501,
     last_update_time:'1347639541501',
     last_update_time:'1347639541501',
-    num_jobs_total:5,
-    num_jobs_completed:0,
-    input: 11,
-    output: 30,
     app_id:1,
     app_id:1,
     jobs:[1, 2, 3, 4, 5]
     jobs:[1, 2, 3, 4, 5]
   },
   },
@@ -72,10 +124,6 @@ App.Run.FIXTURES = [
     user_name:'user1',
     user_name:'user1',
     start_time:1347339951502,
     start_time:1347339951502,
     last_update_time:'1347439951502',
     last_update_time:'1347439951502',
-    num_jobs_total:5,
-    num_jobs_completed:2,
-    input: 10,
-    output: 30,
     app_id:4,
     app_id:4,
     jobs:[4, 5, 1, 3, 6]
     jobs:[4, 5, 1, 3, 6]
   },
   },
@@ -87,10 +135,6 @@ App.Run.FIXTURES = [
     user_name:'user2',
     user_name:'user2',
     start_time:1341539841503,
     start_time:1341539841503,
     last_update_time:'1341639841503',
     last_update_time:'1341639841503',
-    num_jobs_total:5,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:1,
     app_id:1,
     jobs:[6, 7, 8, 9, 10]
     jobs:[6, 7, 8, 9, 10]
   },
   },
@@ -102,10 +146,7 @@ App.Run.FIXTURES = [
     user_name:'user1',
     user_name:'user1',
     start_time:1347539591504,
     start_time:1347539591504,
     last_update_time:'1347639591504',
     last_update_time:'1347639591504',
-    num_jobs_total:3,
     num_jobs_completed:0,
     num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:2,
     app_id:2,
     jobs:[8, 9, 10]
     jobs:[8, 9, 10]
   },
   },
@@ -117,10 +158,6 @@ App.Run.FIXTURES = [
     user_name:'user5',
     user_name:'user5',
     start_time:1347531541505,
     start_time:1347531541505,
     last_update_time:'1347631541505',
     last_update_time:'1347631541505',
-    num_jobs_total:3,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:2,
     app_id:2,
     jobs:[8, 9, 10]
     jobs:[8, 9, 10]
   },
   },
@@ -132,10 +169,6 @@ App.Run.FIXTURES = [
     user_name:'user1',
     user_name:'user1',
     start_time:1342439541506,
     start_time:1342439541506,
     last_update_time:'1342639541506',
     last_update_time:'1342639541506',
-    num_jobs_total:3,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:2,
     app_id:2,
     jobs:[8, 9, 10]
     jobs:[8, 9, 10]
   },
   },
@@ -147,10 +180,6 @@ App.Run.FIXTURES = [
     user_name:'jsmith',
     user_name:'jsmith',
     start_time:1347539541507,
     start_time:1347539541507,
     last_update_time:'1347639541507',
     last_update_time:'1347639541507',
-    num_jobs_total:4,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:4,
     app_id:4,
     jobs:[1, 3, 5, 7]
     jobs:[1, 3, 5, 7]
   },
   },
@@ -162,10 +191,6 @@ App.Run.FIXTURES = [
     user_name:'jsmith',
     user_name:'jsmith',
     start_time:1347539541508,
     start_time:1347539541508,
     last_update_time:'1347639541508',
     last_update_time:'1347639541508',
-    num_jobs_total:4,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:3,
     app_id:3,
     jobs:[1, 3, 5, 7]
     jobs:[1, 3, 5, 7]
   },
   },
@@ -177,10 +202,6 @@ App.Run.FIXTURES = [
     user_name:'user1',
     user_name:'user1',
     start_time:1347539541509,
     start_time:1347539541509,
     last_update_time:'1347639541509',
     last_update_time:'1347639541509',
-    num_jobs_total:4,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:3,
     app_id:3,
     jobs:[1, 3, 5, 7]
     jobs:[1, 3, 5, 7]
   },
   },
@@ -192,10 +213,6 @@ App.Run.FIXTURES = [
     user_name:'user1',
     user_name:'user1',
     start_time:1347539541510,
     start_time:1347539541510,
     last_update_time:'1347639541510',
     last_update_time:'1347639541510',
-    num_jobs_total:4,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:3,
     app_id:3,
     jobs:[1, 3, 5, 7]
     jobs:[1, 3, 5, 7]
   },
   },
@@ -207,10 +224,6 @@ App.Run.FIXTURES = [
     user_name:'user1',
     user_name:'user1',
     start_time:1347539541511,
     start_time:1347539541511,
     last_update_time:'1347639541511',
     last_update_time:'1347639541511',
-    num_jobs_total:4,
-    num_jobs_completed:0,
-    input: 10,
-    output: 30,
     app_id:3,
     app_id:3,
     jobs:[1, 3, 5, 7]
     jobs:[1, 3, 5, 7]
   }
   }

+ 5 - 2
ambari-web/app/models/service.js

@@ -210,9 +210,10 @@ App.Service.FIXTURES = [
   {
   {
     id:4,
     id:4,
     service_name:'zookeeper',
     service_name:'zookeeper',
-    label:'Zookeeper',
+    label:'ZooKeeper',
     health_status:App.Service.Health.stop,
     health_status:App.Service.Health.stop,
     work_status:false,
     work_status:false,
+    components:[1, 2, 3],
     alerts:[7, 8]
     alerts:[7, 8]
   },
   },
   {
   {
@@ -221,14 +222,16 @@ App.Service.FIXTURES = [
     label:'Oozie',
     label:'Oozie',
     health_status:App.Service.Health.dead,
     health_status:App.Service.Health.dead,
     work_status:false,
     work_status:false,
+    components:[8],
     alerts:[9, 10]
     alerts:[9, 10]
   },
   },
   {
   {
     id:6,
     id:6,
     service_name:'hive',
     service_name:'hive',
-    label:'Hive',
+    label:'Hive + HCatalog',
     health_status:App.Service.Health.dead,
     health_status:App.Service.Health.dead,
     work_status:false,
     work_status:false,
+    components:[5],
     alerts:[11, 12]
     alerts:[11, 12]
   }
   }
 ];
 ];

+ 12 - 12
ambari-web/app/router.js

@@ -49,21 +49,21 @@ App.Router = Em.Router.extend({
     });*/
     });*/
   },
   },
 
 
-
-  setInstallerCurrentStep: function (currentStep, completed) {
-    App.db.setInstallerCurrentStep(currentStep, completed);
-    this.set('installerController.currentStep', currentStep);
+  /**
+   * Temporary fix for getting cluster name
+   * @return {*}
+   */
+  getClusterName: function(){
+    return App.db.getClusterName();
   },
   },
 
 
+
+  /**
+   * Get current step of Installer wizard
+   * @return {*}
+   */
   getInstallerCurrentStep: function () {
   getInstallerCurrentStep: function () {
-    var loginName = this.getLoginName();
-    var currentStep = App.db.getInstallerCurrentStep();
-    console.log('getInstallerCurrentStep: loginName=' + loginName + ", currentStep=" + currentStep);
-    if (!currentStep) {
-      currentStep = '1';
-    }
-    console.log('returning currentStep=' + currentStep);
-    return currentStep;
+    return this.getWizardCurrentStep('installer');
   },
   },
 
 
   /**
   /**

+ 0 - 1
ambari-web/app/routes/add_host_routes.js

@@ -24,7 +24,6 @@ module.exports = Em.Route.extend({
 
 
     Ember.run.next(function () {
     Ember.run.next(function () {
       var addHostController = router.get('addHostController');
       var addHostController = router.get('addHostController');
-      addHostController.loadAllPriorSteps();
       router.transitionTo('step' + addHostController.get('currentStep'));
       router.transitionTo('step' + addHostController.get('currentStep'));
     });
     });
 
 

+ 0 - 1
ambari-web/app/routes/add_service_routes.js

@@ -24,7 +24,6 @@ module.exports = Em.Route.extend({
 
 
     Ember.run.next(function () {
     Ember.run.next(function () {
       var addServiceController = router.get('addServiceController');
       var addServiceController = router.get('addServiceController');
-      addServiceController.loadAllPriorSteps();
       router.transitionTo('step' + addServiceController.get('currentStep'));
       router.transitionTo('step' + addServiceController.get('currentStep'));
     });
     });
 
 

+ 23 - 17
ambari-web/app/routes/installer.js

@@ -28,10 +28,12 @@ module.exports = Em.Route.extend({
     if (router.getAuthenticated()) {
     if (router.getAuthenticated()) {
       router.get('mainController').stopLoadOperationsPeriodically();
       router.get('mainController').stopLoadOperationsPeriodically();
       console.log('In installer with successful authenticated');
       console.log('In installer with successful authenticated');
-      // router.loadAllPriorSteps(router.getInstallerCurrentStep());
+
       Ember.run.next(function () {
       Ember.run.next(function () {
-        router.transitionTo('step' + router.getInstallerCurrentStep());
+        var installerController = router.get('installerController');
+        router.transitionTo('step' + installerController.get('currentStep'));
       });
       });
+
     } else {
     } else {
       console.log('In installer but its not authenticated');
       console.log('In installer but its not authenticated');
       console.log('value of authenticated is: ' + router.getAuthenticated());
       console.log('value of authenticated is: ' + router.getAuthenticated());
@@ -49,7 +51,9 @@ module.exports = Em.Route.extend({
       this._super(router, event);
       this._super(router, event);
     } else {
     } else {
       router.set('backBtnForHigherStep', true);
       router.set('backBtnForHigherStep', true);
-      router.transitionTo('step' + router.getInstallerCurrentStep());
+
+      var installerController = router.get('installerController');
+      router.transitionTo('step' + installerController.get('currentStep'));
     }
     }
   },
   },
 
 
@@ -63,7 +67,7 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router) {
     connectOutlets: function (router) {
       console.log('in installer.step1:connectOutlets');
       console.log('in installer.step1:connectOutlets');
       var controller = router.get('installerController');
       var controller = router.get('installerController');
-      router.setInstallerCurrentStep('1', false);
+      controller.setCurrentStep('1', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep1', controller.get('content'));
       controller.connectOutlet('wizardStep1', controller.get('content'));
     },
     },
@@ -81,10 +85,9 @@ module.exports = Em.Route.extend({
     route: '/step2',
     route: '/step2',
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step2');
       router.setNavigationFlow('step2');
-      var controller = router.get('installerController');
-      router.setInstallerCurrentStep('2', false);
 
 
       var controller = router.get('installerController');
       var controller = router.get('installerController');
+      controller.setCurrentStep('2', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep2', controller.get('content.hosts'));
       controller.connectOutlet('wizardStep2', controller.get('content.hosts'));
     },
     },
@@ -118,7 +121,7 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router) {
     connectOutlets: function (router) {
       console.log('in installer.step3:connectOutlets');
       console.log('in installer.step3:connectOutlets');
       var controller = router.get('installerController');
       var controller = router.get('installerController');
-      router.setInstallerCurrentStep('3', false);
+      controller.setCurrentStep('3', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep3', controller.get('content'));
       controller.connectOutlet('wizardStep3', controller.get('content'));
     },
     },
@@ -149,8 +152,8 @@ module.exports = Em.Route.extend({
     route: '/step4',
     route: '/step4',
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step4');
       router.setNavigationFlow('step4');
-      router.setInstallerCurrentStep('4', false);
       var controller = router.get('installerController');
       var controller = router.get('installerController');
+      controller.setCurrentStep('4', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.loadServices();
       controller.loadServices();
       controller.connectOutlet('wizardStep4', controller.get('content.services'));
       controller.connectOutlet('wizardStep4', controller.get('content.services'));
@@ -173,8 +176,9 @@ module.exports = Em.Route.extend({
     route: '/step5',
     route: '/step5',
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step5');
       router.setNavigationFlow('step5');
-      router.setInstallerCurrentStep('5', false);
+
       var controller = router.get('installerController');
       var controller = router.get('installerController');
+      controller.setCurrentStep('5', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep5', controller.get('content'));
       controller.connectOutlet('wizardStep5', controller.get('content'));
     },
     },
@@ -193,8 +197,9 @@ module.exports = Em.Route.extend({
     route: '/step6',
     route: '/step6',
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       router.setNavigationFlow('step6');
       router.setNavigationFlow('step6');
-      router.setInstallerCurrentStep('6', false);
+
       var controller = router.get('installerController');
       var controller = router.get('installerController');
+      controller.setCurrentStep('6', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep6', controller.get('content'));
       controller.connectOutlet('wizardStep6', controller.get('content'));
     },
     },
@@ -217,7 +222,7 @@ module.exports = Em.Route.extend({
     route: '/step7',
     route: '/step7',
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       var controller = router.get('installerController');
       var controller = router.get('installerController');
-      router.setInstallerCurrentStep('7', false);
+      controller.setCurrentStep('7', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep7', controller.get('content'));
       controller.connectOutlet('wizardStep7', controller.get('content'));
     },
     },
@@ -235,7 +240,7 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       console.log('in installer.step8:connectOutlets');
       console.log('in installer.step8:connectOutlets');
       var controller = router.get('installerController');
       var controller = router.get('installerController');
-      router.setInstallerCurrentStep('8', false);
+      controller.setCurrentStep('8', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep8', controller.get('content'));
       controller.connectOutlet('wizardStep8', controller.get('content'));
     },
     },
@@ -254,7 +259,7 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       console.log('in installer.step9:connectOutlets');
       console.log('in installer.step9:connectOutlets');
       var controller = router.get('installerController');
       var controller = router.get('installerController');
-      router.setInstallerCurrentStep('9', false);
+      controller.setCurrentStep('9', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       if (!App.testMode) {              //if test mode is ON don't disable prior steps link.
       if (!App.testMode) {              //if test mode is ON don't disable prior steps link.
         controller.setLowerStepsDisable(9);
         controller.setLowerStepsDisable(9);
@@ -262,7 +267,7 @@ module.exports = Em.Route.extend({
       controller.connectOutlet('wizardStep9', controller.get('content'));
       controller.connectOutlet('wizardStep9', controller.get('content'));
     },
     },
     back: Em.Router.transitionTo('step8'),
     back: Em.Router.transitionTo('step8'),
-    retry: function (router, context) {
+    retry: function (router) {
       var installerController = router.get('installerController');
       var installerController = router.get('installerController');
       var wizardStep9Controller = router.get('wizardStep9Controller');
       var wizardStep9Controller = router.get('wizardStep9Controller');
       installerController.installServices();
       installerController.installServices();
@@ -282,16 +287,17 @@ module.exports = Em.Route.extend({
     connectOutlets: function (router, context) {
     connectOutlets: function (router, context) {
       console.log('in installer.step10:connectOutlets');
       console.log('in installer.step10:connectOutlets');
       var controller = router.get('installerController');
       var controller = router.get('installerController');
-      router.setInstallerCurrentStep('10', false);
+      controller.setCurrentStep('10', false);
       controller.loadAllPriorSteps();
       controller.loadAllPriorSteps();
       controller.connectOutlet('wizardStep10',controller.get('content'));
       controller.connectOutlet('wizardStep10',controller.get('content'));
     },
     },
     back: Em.Router.transitionTo('step9'),
     back: Em.Router.transitionTo('step9'),
     complete: function (router, context) {
     complete: function (router, context) {
       if (true) {   // this function will be moved to installerController where it will validate
       if (true) {   // this function will be moved to installerController where it will validate
-        router.setInstallerCurrentStep('1', true);
+        var controller = router.get('installerController');
+        controller.setCurrentStep('1', false);
         router.setSection('main');
         router.setSection('main');
-        router.transitionTo('main');
+        router.transitionTo('main.index');
       } else {
       } else {
         console.log('cluster installation failure');
         console.log('cluster installation failure');
       }
       }

+ 7 - 6
ambari-web/app/routes/main.js

@@ -23,9 +23,6 @@ module.exports = Em.Route.extend({
     if (router.getAuthenticated()) {
     if (router.getAuthenticated()) {
       router.get('mainController').startLoadOperationsPeriodically();
       router.get('mainController').startLoadOperationsPeriodically();
       // TODO: redirect to last known state
       // TODO: redirect to last known state
-       Ember.run.next(function () {
-         router.transitionTo('dashboard');
-       });
     } else {
     } else {
       Ember.run.next(function () {
       Ember.run.next(function () {
         router.transitionTo('login');
         router.transitionTo('login');
@@ -38,6 +35,13 @@ module.exports = Em.Route.extend({
     redirectsTo:'dashboard'
     redirectsTo:'dashboard'
   }),
   }),
 
 
+  test: Em.Route.extend({
+    route: '/test',
+    connectOutlets:function (router, context) {
+      router.get('mainController').connectOutlet('mainTest');
+    }
+  }),
+
   connectOutlets:function (router, context) {
   connectOutlets:function (router, context) {
     router.get('applicationController').connectOutlet('main');
     router.get('applicationController').connectOutlet('main');
   },
   },
@@ -320,9 +324,6 @@ module.exports = Em.Route.extend({
     service:Em.Route.extend({
     service:Em.Route.extend({
       route:'/:service_id',
       route:'/:service_id',
       connectOutlets:function (router, service) {
       connectOutlets:function (router, service) {
-//        if (service.name == "undefined") {
-//          service = App.Service.find(1);
-//        }
         router.get('mainServiceController').connectOutlet('mainServiceItem', service);
         router.get('mainServiceController').connectOutlet('mainServiceItem', service);
         router.transitionTo('summary');
         router.transitionTo('summary');
       },
       },

+ 102 - 71
ambari-web/app/styles/application.less

@@ -212,8 +212,23 @@ h1 {
     padding-left: 0;
     padding-left: 0;
   }
   }
   #installOptions {
   #installOptions {
+    .sshKey-file-view {
+      width: 486px;
+      height: 200px;
+      overflow-y: auto;
+      border: 1px solid #ccc;
+      margin-top: 5px;
+      padding: 8px;
+      font-family: Consolas,"Liberation Mono",Courier,monospace;
+    }
+    .manual-install {
+      margin-top: 10px;
+    }
     #targetHosts {
     #targetHosts {
 
 
+    }
+    .span6{
+      min-width: 504px;
     }
     }
     #hostConnectivity {
     #hostConnectivity {
       margin-top: 20px;
       margin-top: 20px;
@@ -247,68 +262,6 @@ h1 {
   #step6 .pre-scrollable {
   #step6 .pre-scrollable {
     max-height: 440px;
     max-height: 440px;
   }
   }
-  #serviceConfig {
-    .accordion-heading {
-      background-color: #f0f0f0;
-    }
-    .accordion-group {
-      margin-bottom: 20px;
-      .control-group {
-        margin: 10px 0;
-      }
-      form {
-        margin-bottom: 0;
-      }
-    }
-    .badge {
-      margin-left: 4px;
-    }
-    .slave-component-group-menu {
-      float: left;
-      .nav {
-        margin-bottom: 10px;
-      }
-      .nav li {
-        position: relative;
-        a {
-          padding-right: 24px;
-        }
-        .icon-remove {
-          border: 1px solid white;
-          position: absolute;
-          right: 7px;
-          top: 10px;
-          z-index: 2;
-          cursor: default;
-          color: #555555;
-        }
-        .icon-remove:hover {
-          border: 1px solid grey;
-        }
-      }
-    }
-    .remove-group-error {
-      display: none;
-    }
-    .add-slave-component-group {
-      margin-bottom: 10px;
-    }
-    .master-host, .master-hosts, .slave-hosts {
-      padding-top: 5px;
-      line-height: 20px;
-    }
-    #attention {
-      margin: 20px 0;
-    }
-    .retyped-password {
-      margin-left: 14px;
-    }
-    #slave-hosts-popup {
-      ul {
-        list-style-type: none;
-      }
-    }
-  }
   #deploy {
   #deploy {
     #overallProgress {
     #overallProgress {
     }
     }
@@ -336,6 +289,69 @@ h1 {
   }
   }
 }
 }
 
 
+#serviceConfig {
+  .accordion-heading {
+    background-color: #f0f0f0;
+  }
+  .accordion-group {
+    margin-bottom: 20px;
+    .control-group {
+      margin: 10px 0;
+    }
+    form {
+      margin-bottom: 0;
+    }
+  }
+  .badge {
+    margin-left: 4px;
+  }
+  .slave-component-group-menu {
+    float: left;
+    .nav {
+      margin-bottom: 10px;
+    }
+    .nav li {
+      position: relative;
+      a {
+        padding-right: 24px;
+      }
+      .icon-remove {
+        border: 1px solid white;
+        position: absolute;
+        right: 7px;
+        top: 10px;
+        z-index: 2;
+        cursor: default;
+        color: #555555;
+      }
+      .icon-remove:hover {
+        border: 1px solid grey;
+      }
+    }
+  }
+  .remove-group-error {
+    display: none;
+  }
+  .add-slave-component-group {
+    margin-bottom: 10px;
+  }
+  .master-host, .master-hosts, .slave-hosts {
+    padding-top: 5px;
+    line-height: 20px;
+  }
+  #attention {
+    margin: 20px 0;
+  }
+  .retyped-password {
+    margin-left: 14px;
+  }
+  #slave-hosts-popup {
+    ul {
+      list-style-type: none;
+    }
+  }
+}
+
 a:focus {
 a:focus {
   outline: none;
   outline: none;
 }
 }
@@ -491,6 +507,7 @@ a:focus {
   border-collapse: collapse;
   border-collapse: collapse;
 
 
   td.summary-label {
   td.summary-label {
+    width: 180px;
     text-align: right;
     text-align: right;
   }
   }
 
 
@@ -628,16 +645,16 @@ a:focus {
 #services-menu {
 #services-menu {
   .nav-list {
   .nav-list {
     .tab-marker-position {
     .tab-marker-position {
-
       background-position: 6px 5px;
       background-position: 6px 5px;
       background-repeat: no-repeat;
       background-repeat: no-repeat;
       list-style: none;
       list-style: none;
       height: 20px;
       height: 20px;
       width: 20px;
       width: 20px;
-      margin-left: 0; //      padding-left: 30px;
-    //      padding-right: 30px;
-    //      background-position: 12px 9px;
-    //      background-repeat: no-repeat;
+      margin-left: 0;
+      // padding-left: 30px;
+      // padding-right: 30px;
+      // background-position: 12px 9px;
+      // background-repeat: no-repeat;
     }
     }
     .health-status-LIVE {
     .health-status-LIVE {
       .tab-marker-position;
       .tab-marker-position;
@@ -647,6 +664,9 @@ a:focus {
       .tab-marker-position;
       .tab-marker-position;
       background-image: @status-dead-marker;
       background-image: @status-dead-marker;
     }
     }
+    .health-status-undefined {
+      .tab-marker-position;
+    }
     li {
     li {
       line-height: 24px;
       line-height: 24px;
     }
     }
@@ -749,6 +769,15 @@ a:focus {
   .health-status-DEAD-YELLOW {
   .health-status-DEAD-YELLOW {
     background-image: @status-dead-yellow-marker;
     background-image: @status-dead-yellow-marker;
   }
   }
+  .host-name-search{
+    position: relative;
+    top: 0px;
+    left: 10px;
+  }
+  .host-name-pos{
+    position: relative;
+    top: 10px;
+  }
   .box-header {
   .box-header {
     .btn-group {
     .btn-group {
       float: left;
       float: left;
@@ -766,7 +795,7 @@ a:focus {
       background: #EDF5FC;
       background: #EDF5FC;
     }
     }
     th, td {
     th, td {
-      width: 130px;
+      width: 82px;
     }
     }
     th.first, td.first {
     th.first, td.first {
       width: 30px;
       width: 30px;
@@ -856,6 +885,9 @@ a:focus {
   }
   }
 
 
   #host-details {
   #host-details {
+
+    margin-top: 27px;
+
     .component-operation-button{
     .component-operation-button{
       background-color: #E5E5E5;
       background-color: #E5E5E5;
       background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#E5E5E5), to(#F1F1F1));
       background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#E5E5E5), to(#F1F1F1));
@@ -1580,7 +1612,7 @@ ul.inline li {
 
 
 #host-details > .host-maintenance {
 #host-details > .host-maintenance {
   text-align: right;
   text-align: right;
-  margin-top: -20px;
+  margin-top: -28px;
 }
 }
 
 
 #host-details > .host-maintenance > div {
 #host-details > .host-maintenance > div {
@@ -1626,9 +1658,8 @@ ul.inline li {
 }
 }
 
 
 #step8-content {
 #step8-content {
-  max-height: 570px;
+  max-height: 440px;
 }
 }
-
 #step10-content {
 #step10-content {
   max-height: 440px;
   max-height: 440px;
 }
 }

+ 15 - 4
ambari-web/app/styles/apps.less

@@ -5,9 +5,12 @@
   .table thead th{
   .table thead th{
     vertical-align:top;
     vertical-align:top;
   }
   }
-  .avg-table td {
-    text-align:center;
-    border:none;
+  .avg-table {
+    background-color: #F9F9F9;
+    td {
+      text-align:center;
+      border:none;
+    }
   }
   }
   td.avg-star{
   td.avg-star{
     border-left:1px solid #DDD;
     border-left:1px solid #DDD;
@@ -107,9 +110,17 @@
   }
   }
   #graph1 {
   #graph1 {
     margin-left: 30px;
     margin-left: 30px;
+    width: 440px;
+    #legend_container {
+      margin: 40px 0 0 20px;
+    }
   }
   }
   #graph2 {
   #graph2 {
     margin-right: 30px;
     margin-right: 30px;
+    width: 500px;
+    #tasks_legend_container {
+      margin: 40px 0 0 20px;
+    }
   }
   }
 
 
   tr.containerRow > td{
   tr.containerRow > td{
@@ -140,7 +151,7 @@
   td .table-striped tbody
   td .table-striped tbody
   tr:nth-child(odd) td,
   tr:nth-child(odd) td,
   tr:nth-child(even) th{
   tr:nth-child(even) th{
-    background: none;
+    background-color: none;
   }
   }
 
 
   .sorting_asc { background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAEwATAwERAAIRAQMRAf/EAHgAAAMBAQAAAAAAAAAAAAAAAAAFCAYKAQACAQUAAAAAAAAAAAAAAAAABQMCBAYHCBAAAQUAAQMEAwAAAAAAAAAAAwECBAUGABESByExIghBMxQRAAIBAwMDAwUAAAAAAAAAAAECAwAEBRESBiExUUHhB2GBIhMU/9oADAMBAAIRAxEAPwDvA8k+Qc54sxGj32qlNi0ucrjTj/JqGlmROyJXQ2u/bOsZTmBExPd70/HXmQcW41lOX5+145h0L391KEHhR3Z28Ii6sx9AKgubiO1gaeU6Io19h9TUg/S/7eP+wia3NbBIFbuqiyn3VTCjIMArHHTJarEDGGiNU8vOKVsc7/VxBuGR3yV683X86/Cq/GpssrhP2S8emiSKRm1JS5VfyLH0WfQug7KwZR0CilWHy39++ObQTgkgeV9ux+xq9uc6U8pLfZzP6mClZpKWrvq1DilJAt4Mewh/0hRyBOsaUMoVKLvXtVU6t6+nL/HZTJYi4/rxU81tdbSu+N2Rtp7jcpB0OnUa9aoeOOVdsgDL4I1pFS+NPHmcsQ2+fw+UpLWOwwwWNVQ1kCaIcgaiONkmLGEZrDDXtcnXo5PfjC+5VybKWrWWSyF5cWbEEpJNI6kqdQSrMRqD1B9KjS2t423xoqt5AArb8QVPRwoo4UUcKK//2Q==) no-repeat 85% 50%; }
   .sorting_asc { background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAZAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgICAgICAgICAwMDAwMDAwMDAwEBAQEBAQECAQECAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgAEwATAwERAAIRAQMRAf/EAHgAAAMBAQAAAAAAAAAAAAAAAAAFCAYKAQACAQUAAAAAAAAAAAAAAAAABQMCBAYHCBAAAQUAAQMEAwAAAAAAAAAAAwECBAUGABESByExIghBMxQRAAIBAwMDAwUAAAAAAAAAAAECAwAEBRESBiExUUHhB2GBIhMU/9oADAMBAAIRAxEAPwDvA8k+Qc54sxGj32qlNi0ucrjTj/JqGlmROyJXQ2u/bOsZTmBExPd70/HXmQcW41lOX5+145h0L391KEHhR3Z28Ii6sx9AKgubiO1gaeU6Io19h9TUg/S/7eP+wia3NbBIFbuqiyn3VTCjIMArHHTJarEDGGiNU8vOKVsc7/VxBuGR3yV683X86/Cq/GpssrhP2S8emiSKRm1JS5VfyLH0WfQug7KwZR0CilWHy39++ObQTgkgeV9ux+xq9uc6U8pLfZzP6mClZpKWrvq1DilJAt4Mewh/0hRyBOsaUMoVKLvXtVU6t6+nL/HZTJYi4/rxU81tdbSu+N2Rtp7jcpB0OnUa9aoeOOVdsgDL4I1pFS+NPHmcsQ2+fw+UpLWOwwwWNVQ1kCaIcgaiONkmLGEZrDDXtcnXo5PfjC+5VybKWrWWSyF5cWbEEpJNI6kqdQSrMRqD1B9KjS2t423xoqt5AArb8QVPRwoo4UUcKK//2Q==) no-repeat 85% 50%; }

+ 2 - 4
ambari-web/app/templates/login.hbs

@@ -26,8 +26,6 @@
     <label>{{t login.username}}</label>
     <label>{{t login.username}}</label>
     {{view Ember.TextField valueBinding="loginName" class="span4"}}
     {{view Ember.TextField valueBinding="loginName" class="span4"}}
     <label>{{t login.password}}</label>
     <label>{{t login.password}}</label>
-    {{view Ember.TextField type="password" valueBinding="password" class="span4"}}
-    <div>
-        <a class="btn btn-success" {{action "submit" target="controller"}}>{{t login.loginButton}}</a>
-    </div>
+    {{view view.passTextField type="password" valueBinding="password" class="span4"}}
+        <button class="btn btn-success" {{action "submit" target="controller"}}>{{t login.loginButton}}</button>
 </div>
 </div>

+ 6 - 6
ambari-web/app/templates/main/apps.hbs

@@ -54,12 +54,12 @@
             </tbody>
             </tbody>
   </table>
   </table>
     <div id="filter_info" class="row">
     <div id="filter_info" class="row">
-      <div class="span3">Show:
-        <a href="javascript:void(0)" class="selected" {{action "changeViewType" target="view"}} data-view-type="all">All ({{view.content.length}})</a> &#124;
-        <a href="javascript:void(0)" {{action "changeViewType" target="view"}} data-view-type="filtered">Filtered ({{view.filtered}})</a> &#124;
-        <a href="javascript:void(0)" {{action "changeViewType" target="view"}} data-view-type="starred">Starred ({{view.staredData.count}})</a>
+      <div class="span3" id="filter_buttons">Show:
+        <a href="javascript:void(0)" class="all selected" {{action "clickViewType" target="view"}} data-view-type="all">All ({{view.content.length}})</a> &#124;
+        <a href="javascript:void(0)" class="filtered" {{action "clickViewType" target="view"}} data-view-type="filtered">Filtered ({{view.filtered}})</a> &#124;
+        <a href="javascript:void(0)" class="stared" {{action "clickViewType" target="view"}} data-view-type="starred">Starred ({{view.staredData.count}})</a>
       </div>
       </div>
-      <div class="span2"><a href="#" {{action "clearFilters" target="view"}}>Clear filters</a>&nbsp;&#124;&nbsp;<a href="#" {{action "clearStars" target="controller"}}>Clear stars</a></div>
+      <div class="span2"><a href="#" {{action "clearFilters" target="view"}}>Clear filters</a>&nbsp;&#124;&nbsp;<a href="#" {{action "clearStars" target="view"}}>Clear stars</a></div>
     </div>
     </div>
     <div>
     <div>
     </div>
     </div>
@@ -78,7 +78,7 @@
       <th>Run Date</th>
       <th>Run Date</th>
     </tr>
     </tr>
     <tr>
     <tr>
-      <th></th>
+      <th>{{view view.starFilterView viewName="starFilterViewInstance"}}</th>
       <th>{{view view.appidFilterView}}</th>
       <th>{{view view.appidFilterView}}</th>
       <th>{{view view.nameFilterView}}</th>
       <th>{{view view.nameFilterView}}</th>
       <th>{{view view.typeSelectView}}</th>
       <th>{{view view.typeSelectView}}</th>

+ 4 - 4
ambari-web/app/templates/main/apps/item/bar.hbs

@@ -29,26 +29,26 @@
 </div>
 </div>
 <div></div>
 <div></div>
 <div id="graph1" class="pull-left">
 <div id="graph1" class="pull-left">
-  <div style="float:left">
+  <div class="pull-left">
     <div id="graph1_desc" class="graph_desc">
     <div id="graph1_desc" class="graph_desc">
       <h4>Job Timeline</h4>
       <h4>Job Timeline</h4>
     </div>
     </div>
     <div id="chart"></div>
     <div id="chart"></div>
     <div id="timeline1"></div>
     <div id="timeline1"></div>
   </div>
   </div>
-  <div id="legend_container" style="margin-top:60px">
+  <div id="legend_container" class="pull-left">
     <div id="legend"></div>
     <div id="legend"></div>
   </div>
   </div>
 </div>
 </div>
 <div id="graph2" class="pull-right">
 <div id="graph2" class="pull-right">
-  <div style="float:left">
+  <div class="pull-left">
     <div id="graph2_desc" class="graph_desc">
     <div id="graph2_desc" class="graph_desc">
       <h4>Job Tasks' View</h4>
       <h4>Job Tasks' View</h4>
     </div>
     </div>
     <div id="job_tasks"></div>
     <div id="job_tasks"></div>
     <div id="timeline2"></div>
     <div id="timeline2"></div>
   </div>
   </div>
-  <div id="tasks_legend_container" style="margin-top:60px">
+  <div id="tasks_legend_container" class="pull-left">
     <div id="tasks_legend"></div>
     <div id="tasks_legend"></div>
   </div>
   </div>
 </div>
 </div>

+ 2 - 2
ambari-web/app/templates/main/apps/item/dag.hbs

@@ -38,8 +38,8 @@
         <td>{{job.status}}</td>
         <td>{{job.status}}</td>
         <td>{{job.maps}}&nbsp;({{job.mapsProgress}}%)</td>
         <td>{{job.maps}}&nbsp;({{job.mapsProgress}}%)</td>
         <td>{{job.reduces}}&nbsp;({{job.reducesProgress}}%)</td>
         <td>{{job.reduces}}&nbsp;({{job.reducesProgress}}%)</td>
-        <td>{{job.input}}</td>
-        <td>{{job.output}}</td>
+        <td>{{job.inputFormatted}}</td>
+        <td>{{job.outputFormatted}}</td>
         <td>{{job.duration}}</td>
         <td>{{job.duration}}</td>
       </tr>
       </tr>
       {{/each}}
       {{/each}}

+ 2 - 2
ambari-web/app/templates/main/apps/list_row.hbs

@@ -22,7 +22,7 @@
 <td>{{run.type}}</td>
 <td>{{run.type}}</td>
 <td>{{run.userName}}</td>
 <td>{{run.userName}}</td>
 <td>{{run.numJobsTotal}}</td>
 <td>{{run.numJobsTotal}}</td>
-<td>{{run.input}}</td>
-<td>{{run.output}}</td>
+<td>{{run.inputFormatted}}</td>
+<td>{{run.outputFormatted}}</td>
 <td>{{run.duration}}</td>
 <td>{{run.duration}}</td>
 <td>{{run.lastUpdateTimeFormatted}} {{#if run.isRunning}}<b class='red'>*</b>{{/if}}</td>
 <td>{{run.lastUpdateTimeFormatted}} {{#if run.isRunning}}<b class='red'>*</b>{{/if}}</td>

+ 26 - 26
ambari-web/app/templates/main/background_operations_popup.hbs

@@ -15,30 +15,30 @@
 * See the License for the specific language governing permissions and
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * limitations under the License.
 -->
 -->
-{{#each operation in backgroundOperations.tasks}}
-{{#view App.MainBackgroundOperation contentBinding="operation"}}
-<a class="open-details" {{action openDetails target="view"}} href="#">
-  <i {{bindAttr class="view.iconClass"}}></i>
-</a>
-{{operation.command}} {{operation.role}} on {{operation.hostname}}
-<div class="operation-details">
-  {{#if operation.details.length}}
-    {{#each detail in operation.details}}
-    <div>{{detail.startTime}}: {{detail.name}}</div>
-    {{/each}}
-  {{/if}}
-  <a {{action showOperationLog target="view"}} href="#">
-    {{#if view.isOpenShowLog}}Hide{{else}}Show{{/if}} operation log
-  </a>
-  {{#if view.isOpenShowLog}}
-  <div class="operation-log">
-    <dl class="dl-horizontal">
-      <dt>exitcode:</dt><dd>{{view.logDetails.exitcode}}</dd>
-      <dt>stdout:</dt><dd>{{view.logDetails.stdout}}</dd>
-      <dt>stderror:</dt><dd>{{view.logDetails.stderror}}</dd>
-    </dl>
-  </div>
-  {{/if}}
-</div>
-{{/view}}
+{{#each operation in backgroundOperations}}
+  {{#view App.MainBackgroundOperation contentBinding="operation"}}
+    <a class="open-details" {{action openDetails target="view"}} href="#">
+      <i {{bindAttr class="view.iconClass"}}></i>
+    </a>
+    {{operation.command}} {{operation.role}} on {{operation.host_name}}
+    <div class="operation-details">
+      {{#if operation.details.length}}
+        {{#each detail in operation.details}}
+        <div>{{detail.startTime}}: {{detail.name}}</div>
+        {{/each}}
+      {{/if}}
+      <a {{action showOperationLog target="view"}} href="#">
+        {{#if view.isOpenShowLog}}Hide{{else}}Show{{/if}} operation log
+      </a>
+      {{#if view.isOpenShowLog}}
+      <div class="operation-log">
+        <dl class="dl-horizontal">
+          <dt>exitcode:</dt><dd>{{view.logDetails.exitcode}}</dd>
+          <dt>stdout:</dt><dd>{{view.logDetails.stdout}}</dd>
+          <dt>stderror:</dt><dd>{{view.logDetails.stderror}}</dd>
+        </dl>
+      </div>
+      {{/if}}
+    </div>
+  {{/view}}
 {{/each}}
 {{/each}}

+ 3 - 3
ambari-web/app/templates/main/dashboard.hbs

@@ -92,8 +92,8 @@
               <div class="span11">
               <div class="span11">
                 <div class="row-fluid">
                 <div class="row-fluid">
                   <div class="span8 title">{{title}}
                   <div class="span8 title">{{title}}
-                    {{#if serviceName}}
-                      <a class="serviceLink" href="{{unbound serviceLink}}">{{serviceName}}</a>
+                    {{#if service.serviceName}}
+                      <a class="serviceLink" href="{{unbound serviceLink}}">{{service.serviceName}}</a>
                     {{/if}}
                     {{/if}}
                   </div>
                   </div>
                   <div class="span4 date-time">{{dateDisplay}}</div>
                   <div class="span4 date-time">{{dateDisplay}}</div>
@@ -107,4 +107,4 @@
       </ul>
       </ul>
     </div>
     </div>
 	</div>
 	</div>
-</div>
+</div>

+ 4 - 4
ambari-web/app/templates/main/dashboard/service/hbase.hbs

@@ -19,7 +19,7 @@
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
+    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     {{/if}}
     {{/if}}
@@ -61,9 +61,9 @@
     <td>
     <td>
       {{#each component in view.service.components}}
       {{#each component in view.service.components}}
       {{#if component.type}}
       {{#if component.type}}
-      <a href="#" {{action selectHost component.host}}>{{component.componentName}}</a>,
+      <a href="#" {{action selectHost component.host}}>{{component.displayName}}</a>,
       {{else}}
       {{else}}
-      <a href="#" {{action filterHosts component}}>{{component.componentName}}</a>
+      <a href="#" {{action filterHosts component}}>{{component.displayName}}</a>
       {{/if}}
       {{/if}}
       {{/each}}
       {{/each}}
     </td>
     </td>
@@ -88,4 +88,4 @@
   </div>
   </div>
   {{/view}}
   {{/view}}
   {{/if}}
   {{/if}}
-</div>
+</div>

+ 4 - 4
ambari-web/app/templates/main/dashboard/service/hdfs.hbs

@@ -19,7 +19,7 @@
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
+    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     {{/if}}
     {{/if}}
@@ -72,9 +72,9 @@
     <td>
     <td>
       {{#each component in view.service.components}}
       {{#each component in view.service.components}}
       {{#if component.type}}
       {{#if component.type}}
-      <a href="#" {{action selectHost component.host}}>{{component.componentName}}</a>,
+      <a href="#" {{action selectHost component.host}}>{{component.displayName}}</a>,
       {{else}}
       {{else}}
-      <a href="#" {{action filterHosts component}}>{{component.componentName}}</a>
+      <a href="#" {{action filterHosts component}}>{{component.displayName}}</a>
       {{/if}}
       {{/if}}
       {{/each}}
       {{/each}}
     </td>
     </td>
@@ -99,4 +99,4 @@
       </div>
       </div>
     {{/view}}
     {{/view}}
   {{/if}}
   {{/if}}
-</div>
+</div>

+ 4 - 4
ambari-web/app/templates/main/dashboard/service/hive.hbs

@@ -19,7 +19,7 @@
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
+    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     {{/if}}
     {{/if}}
@@ -27,10 +27,10 @@
   <div class="summary span">
   <div class="summary span">
     {{#each component in view.service.components}}
     {{#each component in view.service.components}}
     {{#if component.type}}
     {{#if component.type}}
-    <a href="#" {{action selectHost component.host}}>{{component.componentName}}</a>,
+    <a href="#" {{action selectHost component.host}}>{{component.displayName}}</a>,
     {{else}}
     {{else}}
-    <a href="#" {{action filterHosts component}}>{{component.componentName}}</a>
+    <a href="#" {{action filterHosts component}}>{{component.displayName}}</a>
     {{/if}}
     {{/if}}
     {{/each}}
     {{/each}}
   </div>
   </div>
-</div>
+</div>

+ 4 - 4
ambari-web/app/templates/main/dashboard/service/mapreduce.hbs

@@ -18,7 +18,7 @@
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
+    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
       <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
       <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     {{/if}}
     {{/if}}
@@ -72,9 +72,9 @@
     <td>
     <td>
       {{#each component in view.service.components}}
       {{#each component in view.service.components}}
       {{#if component.type}}
       {{#if component.type}}
-      <a href="#" {{action selectHost component.host}}>{{component.componentName}}</a>,
+      <a href="#" {{action selectHost component.host}}>{{component.displayName}}</a>,
       {{else}}
       {{else}}
-      <a href="#" {{action filterHosts component}}>{{component.componentName}}</a>
+      <a href="#" {{action filterHosts component}}>{{component.displayName}}</a>
       {{/if}}
       {{/if}}
       {{/each}}
       {{/each}}
     </td>
     </td>
@@ -99,4 +99,4 @@
   </div>
   </div>
   {{/view}}
   {{/view}}
   {{/if}}
   {{/if}}
-</div>
+</div>

+ 4 - 4
ambari-web/app/templates/main/dashboard/service/oozie.hbs

@@ -19,7 +19,7 @@
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
+    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     {{/if}}
     {{/if}}
@@ -27,10 +27,10 @@
   <div class="summary span">
   <div class="summary span">
     {{#each component in view.service.components}}
     {{#each component in view.service.components}}
     {{#if component.type}}
     {{#if component.type}}
-    <a href="#" {{action selectHost component.host}}>{{component.componentName}}</a>,
+    <a href="#" {{action selectHost component.host}}>{{component.displayName}}</a>,
     {{else}}
     {{else}}
-    <a href="#" {{action filterHosts component}}>{{component.componentName}}</a>
+    <a href="#" {{action filterHosts component}}>{{component.displayName}}</a>
     {{/if}}
     {{/if}}
     {{/each}}
     {{/each}}
   </div>
   </div>
-</div>
+</div>

+ 4 - 4
ambari-web/app/templates/main/dashboard/service/zookeeper.hbs

@@ -19,7 +19,7 @@
 <div class="clearfix">
 <div class="clearfix">
   <div class="name span2">
   <div class="name span2">
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
     {{view App.MainDashboardServiceHealthView serviceBinding="view.service"}}
-    <a {{action selectService view.service href=true}}>{{view.service.label}}</a>
+    <a {{action selectService view.service href=true}}>{{view.service.displayName}}</a>
     {{#if view.criticalAlertsCount}}
     {{#if view.criticalAlertsCount}}
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     <span class="label label-important alerts-count">{{view.criticalAlertsCount}}</span>
     {{/if}}
     {{/if}}
@@ -27,10 +27,10 @@
   <div class="summary span">
   <div class="summary span">
     {{#each component in view.service.components}}
     {{#each component in view.service.components}}
     {{#if component.type}}
     {{#if component.type}}
-    <a href="#" {{action selectHost component.host}}>{{component.componentName}}</a>,
+    <a href="#" {{action selectHost component.host}}>{{component.displayName}}</a>,
     {{else}}
     {{else}}
-    <a href="#" {{action filterHosts component}}>{{component.componentName}}</a>
+    <a href="#" {{action filterHosts component}}>{{component.displayName}}</a>
     {{/if}}
     {{/if}}
     {{/each}}
     {{/each}}
   </div>
   </div>
-</div>
+</div>

+ 9 - 32
ambari-web/app/templates/main/host.hbs

@@ -18,31 +18,7 @@
 <div id="hosts" class="box">
 <div id="hosts" class="box">
   <div class="box-header">
   <div class="box-header">
     <div class="button-section">
     <div class="button-section">
-      <div class="btn-group">
-        <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary dropdown-toggle"
-                                                              data-toggle="dropdown">
-          Assign Rack
-          <span class="caret"></span>
-        </button>
-        <ul class="dropdown-menu">
-          {{#each clusters}}
-          <li>
-            <a href="javascript:void(null)"
-               data-toggle="modal" {{action "assignedToRackPopup" this target="controller"}}>
-              {{clusterName}}
-            </a>
-          </li>
-          {{/each}}
-        </ul>
-      </div>
-     <!-- <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary decommission"
-                                                            data-toggle="modal" {{action "decommissionButtonPopup" target="controller"}}>
-        Decommission
-      </button>
-      <button {{bindAttr disabled="controller.isDisabled"}} class="btn btn-primary"
-                                                            data-toggle="modal" {{action "deleteButtonPopup" target="controller"}}>
-        Delete
-      </button>-->
+      {{view view.RackCombobox}}
       <button class="btn btn-inverse add-host-button" {{action addHost}}>
       <button class="btn btn-inverse add-host-button" {{action addHost}}>
         <i class="icon-plus icon-white"></i>
         <i class="icon-plus icon-white"></i>
         Add New Hosts
         Add New Hosts
@@ -58,15 +34,16 @@
         </label>
         </label>
       </th>
       </th>
       <th class="name">
       <th class="name">
-        <a class="filter-label" href="#" {{action sortByName target="controller" }}>Name
-          {{#if controller.isSort}}
-          <i class="icon-arrow-up"{{bindAttr class="controller.sortClass"}}></i>
-          {{/if}}
-        </a>
+        <div class="host-name-pos">
+          <a class="filter-label" href="#" {{action sortByName target="controller" }}>Name
+            {{#if controller.isSort}}
+            <i class="icon-arrow-up"{{bindAttr class="controller.sortClass"}}></i>
+            {{/if}}
+          </a>
 
 
-        <div class="span1">
-          {{view Ember.TextField placeholder="search" valueBinding="view.filterByName"}}
+          {{view Ember.TextField class="host-name-search" placeholder="search" valueBinding="view.filterByName"}}
         </div>
         </div>
+
       </th>
       </th>
       <th>Rack</th>
       <th>Rack</th>
       <th>CPU</th>
       <th>CPU</th>

+ 1 - 1
ambari-web/app/templates/main/host/details.hbs

@@ -20,7 +20,7 @@
   <a href="javascript:void(null)" data-toggle="modal" {{action backToHostsList}}>Hosts</a> /
   <a href="javascript:void(null)" data-toggle="modal" {{action backToHostsList}}>Hosts</a> /
   <span {{bindAttr class=":host-title view.content.healthClass"}}>{{unbound view.content.hostName}}</span>
   <span {{bindAttr class=":host-title view.content.healthClass"}}>{{unbound view.content.hostName}}</span>
   <div class="host-maintenance">
   <div class="host-maintenance">
-    <div class="btn-group display-inline-block">
+    <div class="host-maintenance-btn btn-group display-inline-block">
       <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
       <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
         {{t services.service.actions.maintenance}}
         {{t services.service.actions.maintenance}}
         <span class="caret"></span>
         <span class="caret"></span>

+ 189 - 104
ambari-web/app/templates/main/service/info/configs.hbs

@@ -16,121 +16,206 @@
 * limitations under the License.
 * limitations under the License.
 -->
 -->
 
 
+<!--<div>-->
+    <!--<fieldset class="fieldset">-->
+     <!--<legend>General</legend>-->
+        <!--<div class="row">-->
+           <!--<div class="span2"> <b>Some HDFS config</b> </div>-->
+           <!--<div class="span2"><input type="text"></div>-->
+        <!--</div>-->
+    <!--</fieldset>-->
 
 
-<div>
-    <fieldset class="fieldset">
-     <legend>General</legend>
-        <div class="row">
-           <div class="span2"> <b>Some HDFS config</b> </div>
-           <div class="span2"><input type="text"></div>
-        </div>
-    </fieldset>
+<!--</div>-->
 
 
-</div>
+<!--<br>-->
 
 
-<br>
+<!--<div>-->
+       <!--<fieldset class="fieldset">-->
+        <!--<legend>NameNode</legend>-->
+          <!--<div class="row">-->
+            <!--<div class="span2"><b>NameNodeSet</b> </div>-->
+            <!--<div class="span2">host0001.com.com</div>-->
 
 
-<div>
-       <fieldset class="fieldset">
-        <legend>NameNode</legend>
-          <div class="row">
-            <div class="span2"><b>NameNodeSet</b> </div>
-            <div class="span2">host0001.com.com</div>
+        <!--</div>-->
+<!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>NameNode directories</b> dfs.name.dir </div>-->
+            <!--<div class="span2"><textarea placeholder="/grid/hadoop/namenode"></textarea></div>-->
 
 
-        </div>
-<br>
-        <div class="row">
-            <div class="span2"><b>NameNode directories</b> dfs.name.dir </div>
-            <div class="span2"><textarea placeholder="/grid/hadoop/namenode"></textarea></div>
+        <!--</div>-->
+<!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>Some NameNode config</b> dfs.name.some </div>-->
+            <!--<div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="2048"><span class="add-on">MB</span></div>-->
+            <!--<div class="span2"></div>-->
 
 
-        </div>
-<br>
-        <div class="row">
-            <div class="span2"><b>Some NameNode config</b> dfs.name.some </div>
-            <div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="2048"><span class="add-on">MB</span></div>
-            <div class="span2"></div>
+        <!--</div>-->
+    <!--</fieldset>-->
+<!--</div>-->
+<!--<br>-->
+<!--<div>-->
+    <!--<fieldset class="fieldset">-->
+        <!--<legend>SNameNode</legend>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>Some NameNode host</b> </div>-->
+            <!--<div class="span2">host0002.com.com</div>-->
+        <!--</div>-->
+    <!--</fieldset>-->
+<!--</div>-->
+<!--<br>-->
+<!--<div>-->
+    <!--<fieldset class="fieldset">-->
+        <!--<legend>DataNode (Default)</legend>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>DataNode hosts</b> </div>-->
+            <!--<div class="span3"><a href="#">host003.com.com and 89 more</a> </div>-->
 
 
-        </div>
-    </fieldset>
-</div>
-<br>
-<div>
-    <fieldset class="fieldset">
-        <legend>SNameNode</legend>
-        <div class="row">
-            <div class="span2"><b>Some NameNode host</b> </div>
-            <div class="span2">host0002.com.com</div>
-        </div>
-    </fieldset>
-</div>
-<br>
-<div>
-    <fieldset class="fieldset">
-        <legend>DataNode (Default)</legend>
-        <div class="row">
-            <div class="span2"><b>DataNode hosts</b> </div>
-            <div class="span3"><a href="#">host003.com.com and 89 more</a> </div>
+        <!--</div>-->
+        <!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>DataNode directories</b> dfs.data.dir</div>-->
+             <!--<div class="span2"><textarea placeholder="/grid/0/hadoop/datanode-->
+                                                      <!--/grid/1/hadoop/datanode-->
+                                                      <!--/grid/2/hadoop/datanode"></textarea></div>-->
 
 
-        </div>
-        <br>
-        <div class="row">
-            <div class="span2"><b>DataNode directories</b> dfs.data.dir</div>
-             <div class="span2"><textarea placeholder="/grid/0/hadoop/datanode
-                                                      /grid/1/hadoop/datanode
-                                                      /grid/2/hadoop/datanode"></textarea></div>
+        <!--</div>-->
+        <!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>Some DataNode config</b> dfs.data.some </div>-->
+            <!--<div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="1024"><span class="add-on">MB</span></div>-->
+            <!--<div class="span2"></div>-->
 
 
-        </div>
-        <br>
-        <div class="row">
-            <div class="span2"><b>Some DataNode config</b> dfs.data.some </div>
-            <div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="1024"><span class="add-on">MB</span></div>
-            <div class="span2"></div>
+        <!--</div>-->
+        <!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>Another DataNode config</b> dfs.data.another</div>-->
+            <!--<div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="512"><span class="add-on">MB</span></div>-->
 
 
-        </div>
-        <br>
-        <div class="row">
-            <div class="span2"><b>Another DataNode config</b> dfs.data.another</div>
-            <div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="512"><span class="add-on">MB</span></div>
+        <!--</div>-->
+   <!--</fieldset>-->
+<!--</div>-->
+<!--<br>-->
+<!--<div>-->
+    <!--<fieldset class="fieldset">-->
+        <!--<legend>DataNode Group A</legend>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>DataNode hosts</b> </div>-->
+            <!--<div class="span3"><a href="#">host0090.com.com and 90 more</a> </div>-->
 
 
-        </div>
-   </fieldset>
-</div>
-<br>
-<div>
-    <fieldset class="fieldset">
-        <legend>DataNode Group A</legend>
-        <div class="row">
-            <div class="span2"><b>DataNode hosts</b> </div>
-            <div class="span3"><a href="#">host0090.com.com and 90 more</a> </div>
+        <!--</div>-->
+        <!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>DataNode directories</b> dfs.data.dir</div>-->
+            <!--<div class="span2"><textarea placeholder="/grid/0/hadoop/datanode-->
+                                                      <!--/grid/1/hadoop/datanode-->
+                                                      <!--/grid/2/hadoop/datanode-->
+                                                      <!--/grid/3/hadoop/datanode"></textarea></div>-->
 
 
+        <!--</div>-->
+        <!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>Some DataNode config</b> dfs.data.another</div>-->
+            <!--<div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="2048"><span class="add-on">MB</span></div>-->
+            <!--<div class="span2"></div>-->
+        <!--</div>-->
+        <!--<br>-->
+        <!--<div class="row">-->
+            <!--<div class="span2"><b>Another DataNode config</b> dfs.data.another</div>-->
+            <!--<div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="128"><span class="add-on">MB</span></div>-->
+        <!--</div>-->
+    <!--</fieldset>-->
+<!--</div>-->
+<!--<br>-->
+      <!--<p align="right"> Need a different settings on certain DataNodes? <a href="#">Add a DataNode group</a>-->
+      <!--<br>-->
+      <!--<br>-->
+      <!--<input class="btn btn-primary" type="button" value="Save and apply changes">-->
+    <!--</p>-->
+     <!--</div>-->
+{{!outlet}}
+<div id="serviceConfig">
+  <div class="accordion">
+    {{#each category in selectedService.configCategories}}
+      <div class="accordion-group">
+        <div class="accordion-heading">
+          <a class="accordion-toggle">
+            {{category.name}}
+          </a>
         </div>
         </div>
-        <br>
-        <div class="row">
-            <div class="span2"><b>DataNode directories</b> dfs.data.dir</div>
-            <div class="span2"><textarea placeholder="/grid/0/hadoop/datanode
-                                                      /grid/1/hadoop/datanode
-                                                      /grid/2/hadoop/datanode
-                                                      /grid/3/hadoop/datanode"></textarea></div>
 
 
-        </div>
-        <br>
-        <div class="row">
-            <div class="span2"><b>Some DataNode config</b> dfs.data.another</div>
-            <div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="2048"><span class="add-on">MB</span></div>
-            <div class="span2"></div>
-        </div>
-        <br>
-        <div class="row">
-            <div class="span2"><b>Another DataNode config</b> dfs.data.another</div>
-            <div class="span2 input-append"><input class="span2" id="appendedInput" type="text" placeholder="128"><span class="add-on">MB</span></div>
-        </div>
-    </fieldset>
-</div>
-<br>
-      <p align="right"> Need a different settings on certain DataNodes? <a href="#">Add a DataNode group</a>
-      <br>
-      <br>
-      <input class="btn btn-primary" type="button" value="Save and apply changes">
-    </p>
-     </div>
-{{outlet}}
+        {{#unless category.isForSlaveComponent}}
+          {{#view App.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs"}}
+            <form class="form-horizontal">
+
+              {{#each view.categoryConfigs}}
+                {{#if isVisible}}
+                  <div {{bindAttr class="errorMessage:error: :control-group"}}>
+                    <label class="control-label">{{displayName}}</label>
+
+                    <div class="controls">
+                      {{view viewClass serviceConfigBinding="this" categoryConfigsBinding="view.categoryConfigs"}}
+                      <span class="help-inline">{{errorMessage}}</span>
+                    </div>
+                  </div>
+                {{/if}}
+              {{/each}}
+
+            </form>
+          {{/view}}
+        {{/unless}}
+
+        {{#if category.isForSlaveComponent}}
+          {{#view App.ServiceConfigsByCategoryView categoryBinding="category" serviceConfigsBinding="selectedService.configs" controllerBinding="App.router.mainServiceSlaveComponentGroupsController"}}
+            <div class="slave-component-group-menu">
+              {{view App.SlaveComponentGroupsMenu}}
+            </div>
+
+            {{#view App.AddSlaveComponentGroupButton slaveComponentNameBinding="category.name"}}
+              <a class="btn add-slave-component-group btn-large" {{action addSlaveComponentGroup target="controller"}}><i
+                class="icon-plus"></i></a>
+            {{/view}}
+            <div class="remove-group-error control-group warning">
+              <span class="help-inline">You cannot delete this group since there are hosts assigned to it. You must assign them to another group before you can delete this group.</span>
+            </div>
+
+            <form class="form-horizontal">
+
+              {{#view App.SlaveComponentChangeGroupNameView}}
+                <label class="control-label">Group name</label>
+
+                <div class="controls">
+                  <div class="span6">
+                    <input class="span9" type="text" {{bindAttr value="view.content.name"}}>
+                    <button class="btn" {{action changeGroupName target="view"}}>Save</button>
+                  </div>
+                  <span class="help-inline">{{view.errorMessage}}</span>
+                </div>
+              {{/view}}
+
+
+              {{#each view.categoryConfigs}}
+                {{#if isVisible}}
+                  <div {{bindAttr class="errorMessage:error: :control-group"}}>
+                    <label class="control-label">{{displayName}}</label>
+
+                    <div class="controls">
+                      {{view viewClass serviceConfigBinding="this" categoryConfigsBinding="view.categoryConfigs"}}
+                      <span class="help-inline">{{errorMessage}}</span>
+                    </div>
+                  </div>
+                {{/if}}
+              {{/each}}
+
+            </form>
+
+          {{/view}}
+        {{/if}}
+      </div>
+    {{/each}}
+  </div>
+  <p class="pull-right">
+    <!--<input class="btn btn-primary" type="button" value="Save and apply changes" {{!bindAttr disabled="isSubmitDisabled"}} />-->
+    <a class="btn btn-primary" {{bindAttr disabled="isSubmitDisabled"}}
+      {{action saveServiceConfigProperties target="controller"}}>Save and apply changes</a>
+  </p>
+</div>

+ 54 - 6
ambari-web/app/templates/main/service/info/summary.hbs

@@ -39,17 +39,23 @@
   <div class="service-content">
   <div class="service-content">
     <table id="summary-info" class="table table-bordered table-striped table-condensed">
     <table id="summary-info" class="table table-bordered table-striped table-condensed">
       <tbody>
       <tbody>
+      {{#unless view.serviceStatus.oozie}}
+      {{#unless view.serviceStatus.hive}}
+      {{#unless view.serviceStatus.zookeeper}}
       {{#each component in controller.content.components}}
       {{#each component in controller.content.components}}
       <tr>
       <tr>
-        {{#if component.type}}
-        <td class="summary-label">{{component.componentName}}</td>
-        <td><a {{action selectHost component.host}} href="javascript:void(null)">{{component.host.hostName}}</a></td>
+        {{#if component.isMaster}}
+        <td class="summary-label">{{component.displayName}}</td>
+        <td><a {{action selectHost component.host}} href="javascript:void(null)">{{component.hostComponents}}</a></td>
         {{else}}
         {{else}}
-        <td class="summary-label">{{component.componentName}}s</td>
-        <td><a {{action filterHosts component}} href="javascript:void(null)">{{component.componentName}}s</a></td>
+        <td class="summary-label">{{component.displayName}}s</td>
+        <td><a {{action filterHosts component}} href="javascript:void(null)">{{component.displayName}}s</a></td>
         {{/if}}
         {{/if}}
       </tr>
       </tr>
       {{/each}}
       {{/each}}
+      {{/unless}}
+      {{/unless}}
+      {{/unless}}
       {{#if view.serviceStatus.hdfs}}
       {{#if view.serviceStatus.hdfs}}
       <tr>
       <tr>
         <td>{{t services.service.summary.version}}</td>
         <td>{{t services.service.summary.version}}</td>
@@ -221,6 +227,48 @@
         </td>
         </td>
       </tr>
       </tr>
       {{/if}}
       {{/if}}
+      {{#if view.serviceStatus.zookeeper}}
+        <tr>
+          <td class="summary-label">Hosts</td>
+          <td>
+            {{#each component in controller.content.components}}
+              <a {{action selectHost component.host}} href="javascript:void(null)">{{component.host.hostName}}</a>
+           {{/each}}
+          </td>
+        </tr>
+      {{/if}}
+      {{#if view.serviceStatus.oozie}}
+        <tr>
+          <td class="summary-label">Hosts</td>
+          <td>
+            {{#each component in controller.content.components}}
+              <a {{action selectHost component.host}} href="javascript:void(null)">{{component.host.hostName}}</a>
+           {{/each}}
+          </td>
+        </tr>
+      {{/if}}
+      {{#if view.serviceStatus.hive}}
+        <tr>
+          <td class="summary-label">Host</td>
+          <td>
+            {{#each component in controller.content.components}}
+              <a {{action selectHost component.host}} href="javascript:void(null)">{{component.host.hostName}}</a>
+           {{/each}}
+          </td>
+        </tr>
+        <tr>
+          <td>Database</td>
+          <td>{{view.data.hive.database}}</td>
+        </tr>
+        <tr>
+          <td>Database Name</td>
+          <td>{{view.data.hive.databaseName}}</td>
+        </tr>
+        <tr>
+          <td>User</td>
+          <td>{{view.data.hive.user}}</td>
+        </tr>
+      {{/if}}
       </tbody>
       </tbody>
     </table>
     </table>
     {{!view view.moreStatsView}}
     {{!view view.moreStatsView}}
@@ -286,4 +334,4 @@
     </div>
     </div>
   </div>
   </div>
 </div>
 </div>
-{{/if}}
+{{/if}}

+ 10 - 21
ambari-web/app/templates/main/service/item.hbs

@@ -32,26 +32,15 @@
       {{/each}}
       {{/each}}
     </ul>
     </ul>
   </div>
   </div>
-  {{#if controller.content.workStatus}}
-    <a href="javascript:void(null)" class="btn disabled">
-      <i class="icon-play"></i>
-      Start
-    </a>
-    <a href="javascript:void(null)" class="btn btn-danger"
-       data-toggle="modal" {{action "stopService" target="controller"}}>
-      <i class="icon-stop icon-white"></i>
-      Stop
-    </a>
-  {{else}}
-    <a href="javascript:void(null)" class="btn btn-success"
-       data-toggle="modal" {{action "startService" target="controller"}}>
-      <i class="icon-play icon-white"></i>
-      Start
-    </a>
-    <a href="javascript:void(null)" class="btn disabled">
-      <i class="icon-stop"></i>
-      Stop
-    </a>
-  {{/if}}
+  <a href="javascript:void(null)" {{bindAttr class=":btn controller.content.workStatus:disabled:btn-success" }}
+     data-toggle="modal" {{action "startService" target="controller"}}>
+    <i class="icon-play"></i>
+    Start
+  </a>
+  <a href="javascript:void(null)" {{bindAttr class=":btn controller.content.workStatus:btn-danger:disabled" }}
+     data-toggle="modal" {{action "stopService" target="controller"}}>
+    <i class="icon-stop icon-white"></i>
+    Stop
+  </a>
 </div>
 </div>
 {{outlet}}
 {{outlet}}

+ 1 - 1
ambari-web/app/templates/main/service/menu_item.hbs

@@ -17,7 +17,7 @@
 -->
 -->
 
 
 <a href="#/main/services/{{unbound view.content.id}}/summary">
 <a href="#/main/services/{{unbound view.content.id}}/summary">
-  {{view App.MainDashboardServiceHealthView serviceBinding="view.content"}}&nbsp;<span>{{unbound view.content.label}}</span>
+  {{view App.MainDashboardServiceHealthView serviceBinding="view.content"}}&nbsp;<span>{{unbound view.content.displayName}}</span>
   {{#if view.serviceOperationsCount}}
   {{#if view.serviceOperationsCount}}
     <span class="label operations-count" {{action "showBackgroundOperationsPopup" target="App.router.mainServiceItemController"}}>
     <span class="label operations-count" {{action "showBackgroundOperationsPopup" target="App.router.mainServiceItemController"}}>
       {{view.serviceOperationsCount}}
       {{view.serviceOperationsCount}}

+ 47 - 0
ambari-web/app/templates/main/test.hbs

@@ -0,0 +1,47 @@
+<!--
+* 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.
+-->
+
+SERVICES
+
+<div>
+  <table style="padding:10px;">
+    <thead>
+    <tr>
+      <th>Service name</th>
+      <th>Component name</th>
+      <th>Component Status</th>
+      <th>Host name</th>
+    </tr>
+    </thead>
+    <tbody>
+    {{#each view.services }}
+    <tr colspan=4>
+      <td style="padding:10px;">{{displayName}}</td>
+    </tr>
+    {{#each components}}
+      <tr>
+        <td></td>
+        <td style="padding:10px;">{{componentName}}</td>
+        <td style="padding:10px;">{{state}}</td>
+        <td style="padding:10px;">{{host_name}}</td>
+      </tr>
+    {{/each}}
+    {{/each}}
+    </tbody>
+  </table>
+</div>

+ 8 - 3
ambari-web/app/templates/wizard/step2.hbs

@@ -54,15 +54,19 @@
       <p>{{t installer.step2.sshKey.info}}</p>
       <p>{{t installer.step2.sshKey.info}}</p>
 
 
       <div {{bindAttr class="sshKeyError:error :control-group"}}>
       <div {{bindAttr class="sshKeyError:error :control-group"}}>
+        {{#if view.isFileApi}}
+          {{view App.SshKeyFileUploader}}
+          <div {{bindAttr class="view.sshKeyPreviewClass"}}>{{content.sshKey}}</div>
+        {{/if}}
         <div class="controls">
         <div class="controls">
-          {{view Ember.TextArea class="span6" rows="4" placeholder="ssh private key" valueBinding="content.sshKey"}}
+          {{view Ember.TextArea class="span6" rows="4" classBinding="view.sshKeyClass"  id="sshKey" placeholder="ssh private key" disabledBinding="view.sshKeyState" valueBinding="content.sshKey"}}
           {{#if sshKeyError}}
           {{#if sshKeyError}}
-        <span
-          class="help-inline">{{sshKeyError}}</span>
+          <span class="help-inline">{{sshKeyError}}</span>
           {{/if}}
           {{/if}}
         </div>
         </div>
       </div>
       </div>
 
 
+      <div class="manual-install">
       <label class="checkbox">
       <label class="checkbox">
         {{t installer.step2.manualInstall.label}}
         {{t installer.step2.manualInstall.label}}
         <a href="javascript:void(null)"
         <a href="javascript:void(null)"
@@ -71,6 +75,7 @@
           Learn more</a>
           Learn more</a>
         {{view Ember.Checkbox checkedBinding="content.manualInstall"}}
         {{view Ember.Checkbox checkedBinding="content.manualInstall"}}
       </label>
       </label>
+      </div>
 
 
       {{#if "manualInstall"}}
       {{#if "manualInstall"}}
       <div class="alert">
       <div class="alert">

+ 1 - 1
ambari-web/app/templates/wizard/step9.hbs

@@ -109,7 +109,7 @@
 
 
   <div>
   <div>
     {{#if view.resultMsg}}
     {{#if view.resultMsg}}
-    <p {{bindAttr class="view.resultMsgColor"}}>{{view.resultMsg}}</p>
+    <p {{bindAttr class="view.resultMsgColor :alert"}}>{{view.resultMsg}}</p>
     {{/if}}
     {{/if}}
     <div class="btn-area">
     <div class="btn-area">
       <a
       <a

+ 133 - 3
ambari-web/app/utils/data_table.js

@@ -39,6 +39,34 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, {
 
 
   "ambari-date-desc": function (a, b) {
   "ambari-date-desc": function (a, b) {
     return b - a;
     return b - a;
+  },
+  /**
+   * Custom methods for correct bandwidth sorting
+   */
+  "ambari-bandwidth-pre": function (bandwidth_string) {
+    debugger;
+    bandwidth_string = (jQuery(bandwidth_string).text()) ? jQuery(bandwidth_string).text() : bandwidth_string;
+    var convertedRowValue;
+    if (bandwidth_string === '<1KB') {
+      convertedRowValue = 1;
+    } else {
+      var rowValueScale = bandwidth_string.substr(bandwidth_string.length - 2, 2);
+      switch (rowValueScale) {
+        case 'KB':
+          convertedRowValue = parseFloat(bandwidth_string)*1024;
+          break;
+        case 'MB':
+          convertedRowValue = parseFloat(bandwidth_string)*1048576;
+          break;
+      }
+    }
+    return convertedRowValue;
+  },
+  "ambari-bandwidth-asc": function (a, b) {
+    return a - b;
+  },
+  "ambari-bandwidth-desc": function (a, b) {
+    return b - a;
   }
   }
 });
 });
 
 
@@ -113,10 +141,11 @@ jQuery.extend(jQuery.fn.dataTableExt.oApi, {
 jQuery.extend($.fn.dataTableExt.afnFiltering.push(
 jQuery.extend($.fn.dataTableExt.afnFiltering.push(
     function (oSettings, aData, iDataIndex) {
     function (oSettings, aData, iDataIndex) {
       var inputFilters = [
       var inputFilters = [
+        {iColumn: '0', elementId: 'star_filter', type: 'star'},
         {iColumn: '4', elementId: 'user_filter', type: 'multiple'},
         {iColumn: '4', elementId: 'user_filter', type: 'multiple'},
         {iColumn: '5', elementId: 'jobs_filter', type: 'number' },
         {iColumn: '5', elementId: 'jobs_filter', type: 'number' },
-        {iColumn: '6', elementId: 'input_filter', type: 'number' },
-        {iColumn: '7', elementId: 'output_filter', type: 'number' },
+        {iColumn: '6', elementId: 'input_filter', type: 'bandwidth' },
+        {iColumn: '7', elementId: 'output_filter', type: 'bandwidth' },
         {iColumn: '8', elementId: 'duration_filter', type: 'time' },
         {iColumn: '8', elementId: 'duration_filter', type: 'time' },
         {iColumn: '9', elementId: 'rundate_filter', type: 'date' }
         {iColumn: '9', elementId: 'rundate_filter', type: 'date' }
       ];
       ];
@@ -143,8 +172,25 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
               timeFilter(jQuery('#' + inputFilters[i].elementId).val(), aData[inputFilters[i].iColumn]);
               timeFilter(jQuery('#' + inputFilters[i].elementId).val(), aData[inputFilters[i].iColumn]);
             }
             }
             break;
             break;
+          case 'bandwidth':
+            if (jQuery('#' + inputFilters[i].elementId).val() && match) {
+              bandwidthFilter(jQuery('#' + inputFilters[i].elementId).val(), aData[inputFilters[i].iColumn]);
+            }
+            break;
+          case 'star':
+            if (jQuery('#' + inputFilters[i].elementId).val() && match) {
+              starFilter(jQuery('#' + inputFilters[i].elementId).val(), aData[inputFilters[i].iColumn]);
+            }
+            break;
         }
         }
       }
       }
+
+      function starFilter(d, rowValue) {
+        match = false;
+        if (rowValue == null) return;
+        if (rowValue.indexOf(d) != -1) match = true;
+      }
+
       function multipleFilter(condition, rowValue) {
       function multipleFilter(condition, rowValue) {
         var options = condition.split(',');
         var options = condition.split(',');
         match = false;
         match = false;
@@ -159,7 +205,7 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
         var compareScale = rangeExp.charAt(rangeExp.length - 1);
         var compareScale = rangeExp.charAt(rangeExp.length - 1);
         var compareValue = isNaN(parseInt(compareScale)) ? parseInt(rangeExp.substr(1, rangeExp.length - 2)) : parseInt(rangeExp.substr(1, rangeExp.length - 1));
         var compareValue = isNaN(parseInt(compareScale)) ? parseInt(rangeExp.substr(1, rangeExp.length - 2)) : parseInt(rangeExp.substr(1, rangeExp.length - 1));
         rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue;
         rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue;
-        var convertedRowValue = parseInt(rowValue.substr(0, 2)) * 3600 + parseInt(rowValue.substr(3, 5)) * 60 + parseInt(rowValue.substr(6, 8));
+        var convertedRowValue = parseInt(rowValue.substr(0, 2)) * 3600 + parseInt(rowValue.substr(3, 2)) * 60 + parseInt(rowValue.substr(6, 2));
         switch (compareScale) {
         switch (compareScale) {
           case 'm':
           case 'm':
             convertedRowValue /= 60;
             convertedRowValue /= 60;
@@ -184,6 +230,49 @@ jQuery.extend($.fn.dataTableExt.afnFiltering.push(
         }
         }
       }
       }
 
 
+      function bandwidthFilter(rangeExp, rowValue) {
+        debugger;
+        var compareChar = rangeExp.charAt(0);
+        var compareScale = rangeExp.charAt(rangeExp.length - 1);
+        var compareValue = isNaN(parseFloat(compareScale)) ? parseFloat(rangeExp.substr(1, rangeExp.length - 2)) : parseFloat(rangeExp.substr(1, rangeExp.length - 1));
+        switch (compareScale) {
+          case 'm':
+            compareValue *= 1048576;
+            break;
+          default:
+            compareValue *= 1024;
+        }
+        rowValue = (jQuery(rowValue).text()) ? jQuery(rowValue).text() : rowValue;
+        var convertedRowValue;
+        if (rowValue === '<1KB') {
+          convertedRowValue = 1;
+        } else {
+          var rowValueScale = rowValue.substr(rowValue.length - 2, 2);
+          switch (rowValueScale) {
+            case 'KB':
+              convertedRowValue = parseFloat(rowValue)*1024;
+              break;
+            case 'MB':
+              convertedRowValue = parseFloat(rowValue)*1048576;
+              break;
+          }
+        }
+        match = false;
+        switch (compareChar) {
+          case '<':
+            if (compareValue > convertedRowValue) match = true;
+            break;
+          case '>':
+            if (compareValue < convertedRowValue) match = true;
+            break;
+          case '=':
+            if (compareValue == convertedRowValue) match = true;
+            break;
+          default:
+            match = false;
+        }
+      }
+
       function dateFilter(condition, rowValue) {
       function dateFilter(condition, rowValue) {
         var nowTime = new Date().getTime();
         var nowTime = new Date().getTime();
         var oneDayPast = nowTime - 86400000;
         var oneDayPast = nowTime - 86400000;
@@ -272,5 +361,46 @@ jQuery.extend(jQuery.fn.dataTableExt.oApi, {
 });
 });
 
 
 
 
+jQuery.fn.dataTableExt.oApi.fnGetColumnData = function ( oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty ) {
+  // check that we have a column id
+  if ( typeof iColumn == "undefined" ) return [];
+
+  // by default we only wany unique data
+  if ( typeof bUnique == "undefined" ) bUnique = true;
+
+  // by default we do want to only look at filtered data
+  if ( typeof bFiltered == "undefined" ) bFiltered = true;
+
+  // by default we do not wany to include empty values
+  if ( typeof bIgnoreEmpty == "undefined" ) bIgnoreEmpty = true;
+
+  // list of rows which we're going to loop through
+  var aiRows;
+
+  // use only filtered rows
+  if (bFiltered == true) aiRows = oSettings.aiDisplay;
+  // use all rows
+  else aiRows = oSettings.aiDisplayMaster; // all row numbers
+
+  // set up data array
+  var asResultData = new Array();
+
+  for (var i=0,c=aiRows.length; i<c; i++) {
+    iRow = aiRows[i];
+    var sValue = this.fnGetData(iRow, iColumn);
+
+    // ignore empty values?
+    if (bIgnoreEmpty == true && sValue.length == 0) continue;
+
+    // ignore unique values?
+    else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue;
+
+    // else push the value onto the result data array
+    else asResultData.push(sValue);
+  }
+
+  return asResultData;
+};
+
 
 
 
 

+ 11 - 4
ambari-web/app/utils/db.js

@@ -273,7 +273,7 @@ App.db.setServiceConfigProperties = function (configProperties) {
 App.db.setClusterStatus = function (status) {
 App.db.setClusterStatus = function (status) {
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
-  App.db.data[user].Installer.clusterStatus = status;
+  App.db.data[user].clusterStatus = status;
   console.log('db.setClusterStatus called: ' + JSON.stringify(status));
   console.log('db.setClusterStatus called: ' + JSON.stringify(status));
   localStorage.setObject('ambari', App.db.data);
   localStorage.setObject('ambari', App.db.data);
 }
 }
@@ -315,7 +315,7 @@ App.db.getClusterName = function () {
   console.log('Trace: Entering db:getClusterName function');
   console.log('Trace: Entering db:getClusterName function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
-  if (user) {
+  if (user && App.db.data[user] && App.db.data[user].Installer) {
     return App.db.data[user].Installer.ClusterName;
     return App.db.data[user].Installer.ClusterName;
   }
   }
 };
 };
@@ -450,7 +450,10 @@ App.db.getHostSlaveComponents = function () {
 App.db.getSlaveComponentHosts = function () {
 App.db.getSlaveComponentHosts = function () {
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.slaveComponentHosts;
+  if(App.db.data[user]&&App.db.data[user].Installer){
+    return App.db.data[user].Installer.slaveComponentHosts;
+  }
+  return null;
 }
 }
 
 
 App.db.getServiceConfigs = function () {
 App.db.getServiceConfigs = function () {
@@ -469,7 +472,11 @@ App.db.getClusterStatus = function () {
   console.log('TRACE: Entering db:getClusterStatus function');
   console.log('TRACE: Entering db:getClusterStatus function');
   App.db.data = localStorage.getObject('ambari');
   App.db.data = localStorage.getObject('ambari');
   var user = App.db.data.app.loginName;
   var user = App.db.data.app.loginName;
-  return App.db.data[user].Installer.clusterStatus;
+  if(App.db.data[user] && App.db.data[user].clusterStatus){
+    return App.db.data[user].clusterStatus;
+  } else {
+    return null;
+  }
 }
 }
 
 
 module.exports = App.db;
 module.exports = App.db;

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

@@ -178,7 +178,7 @@ module.exports = {
         var swatch = '<span class="detail_swatch" style="background-color: ' + series.color + '"></span>';
         var swatch = '<span class="detail_swatch" style="background-color: ' + series.color + '"></span>';
         return swatch + d.label +
         return swatch + d.label +
           '<br>Run-time: ' + formattedY + '<br>Wait-time: ' + formattedX;
           '<br>Run-time: ' + formattedY + '<br>Wait-time: ' + formattedX;
-      },
+      }
 
 
     });
     });
     var annotator = new Rickshaw.Graph.Annotate({
     var annotator = new Rickshaw.Graph.Annotate({

+ 119 - 0
ambari-web/app/utils/http_client.js

@@ -0,0 +1,119 @@
+/**
+ * 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.HttpClient perform an ajax request
+ */
+App.HttpClient = Em.Object.create({
+
+  /**
+   *
+   * @param jqXHR
+   * @param textStatus
+   * @param errorThrown
+   */
+  defaultErrorHandler: function (jqXHR, textStatus, errorThrown) {
+    var json = $.parseJSON(jqXHR.responseText);
+    if (json) {
+      Em.assert("HttpClient:", json);
+    } else {
+      Em.assert("HttpClient:", errorThrown);
+    }
+  },
+
+  /**
+   * @param {string} url
+   * @param {Object} ajaxOptions
+   * @param {App.ServerDataMapper} mapper - json processor
+   * @param {function} errorHandler
+   * @param {number} interval - frequecy request
+   */
+  request: function (url, ajaxOptions, mapper, errorHandler) {
+
+    if (!errorHandler) {
+      errorHandler = this.defaultErrorHandler;
+    }
+
+    var options = {dataType: 'json'}; // default ajax options;
+
+    $.extend(options, {
+      url: url,
+      success: function (data) {
+        mapper.map(data);
+      },
+      error: errorHandler
+    });
+
+    $.extend(options, ajaxOptions);
+
+    $.ajax(options);
+  },
+
+  /**
+   * @param {string} url
+   * @param {App.ServerDataMapper} mapper - json processor
+   * @param {Object} data - ajax data property
+   * @param {function} errorHandler
+   * @param {number} interval - frequecy request
+   */
+  get: function (url, mapper, data, errorHandler, interval) {
+    var client = this;
+    var request = function () {
+      client.request(url, data, mapper, errorHandler);
+    }
+
+    interval = "" + interval;
+    if (interval.match(/\d+/)) {
+      $.periodic({period: interval}, request);
+    } else {
+      request();
+    }
+  },
+
+  /**
+   * @param {string} url
+   * @param {Object} data - ajax data property
+   * @param {App.ServerDataMapper} mapper - json processor
+   * @param {function} errorHandler
+   * @param {number} interval - frequecy request
+   */
+  post: function (url, data, mapper, errorHandler, interval) {
+    this.get(url, data, mapper, errorHandler, interval);
+  }
+
+//  not realized yet
+//  put:function (url, mapper, errorHandler) {
+//    this.request(url, {}, mapper, errorHandler);
+//  },
+//
+//  delete:function (url, mapper, errorHandler) {
+//    this.request(url, {}, mapper, errorHandler);
+//  }
+});
+
+//App.HttpClient.get("/data/hosts/hosts.json", App.hostsMapper);
+
+App.HttpClient.get("/data/dashboard/services.json", App.servicesMapper);
+
+/*App.HttpClient.get(
+  'http://nagiosserver/hdp/nagios/nagios_alerts.php?q1=alerts&alert_type=all',
+  App.alertsMapper,
+  { dataType: 'jsonp', jsonp: 'jsonp' }
+);*/

+ 36 - 0
ambari-web/app/utils/misc.js

@@ -0,0 +1,36 @@
+/**
+ * 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.
+ */
+module.exports = {
+  /**
+   * Convert value from bytes to appropriate measure
+   */
+  formatBandwidth: function (value) {
+    if (value) {
+      if (value < 1024) {
+        value = '<1KB';
+      } else {
+        if (value < 1048576) {
+          value = Math.round(value / 102.4) / 10 + 'KB';
+        } else {
+          value = Math.round(value / 104857.6) / 10 + 'MB';
+        }
+      }
+    }
+    return value;
+  }
+};

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

@@ -22,6 +22,7 @@
 
 
 require('views/application');
 require('views/application');
 require('views/common/chart');
 require('views/common/chart');
+require('views/common/combobox');
 require('views/common/chart/pie');
 require('views/common/chart/pie');
 require('views/common/chart/linear');
 require('views/common/chart/linear');
 require('views/common/chart/linear_time');
 require('views/common/chart/linear_time');
@@ -32,6 +33,7 @@ require('views/common/form/field');
 require('views/common/quick_view_link_view');
 require('views/common/quick_view_link_view');
 require('views/login');
 require('views/login');
 require('views/main');
 require('views/main');
+require('views/main/test');
 require('views/main/menu');
 require('views/main/menu');
 require('views/main/charts');
 require('views/main/charts');
 require('views/main/host');
 require('views/main/host');

+ 72 - 0
ambari-web/app/views/common/combobox.js

@@ -0,0 +1,72 @@
+/**
+ * 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.Combobox = Em.Select.extend({
+  classNames:['combobox'],
+  placeholderText:false,
+  disabled:false,
+
+  input:function () {
+    return this.get('combobox').$element;
+  }.property('combobox'),
+
+  button:function () {
+    return this.get('combobox').$button;
+  }.property('combobox'),
+
+  toggleDisabling:function () {
+    var disabled = this.get('disabled') ? 'disabled' : false;
+
+    this.get('input').attr('disabled', disabled);
+    this.get('button').attr('disabled', disabled);
+
+  }.observes('disabled'),
+
+  content:function () {
+    // convert DS.RecordsArray to array;
+    var content = [
+      {}
+    ];
+    var racks = this.get('recordArray');
+
+    racks.forEach(function (cluster, index) {
+      content.push(cluster);
+    });
+
+    return content;
+  }.property('recordArray'),
+  clearTextFieldValue:function () {
+    var options = [];
+
+    this.get('combobox').$element.val('');
+    this.get('combobox').clearTarget();
+
+  },
+  didInsertElement:function () {
+    this._super();
+    this.set('combobox', this.$().combobox().data('combobox'));
+
+    this.clearTextFieldValue(); // fix of script tags in
+
+    if (this.get('placeholderText')) {
+      this.get('combobox').$element.attr('placeholder', this.get('placeholderText'));
+    }
+  }
+});

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

@@ -21,6 +21,11 @@ var App = require('app');
 
 
 App.LoginView = Em.View.extend({
 App.LoginView = Em.View.extend({
 
 
-  templateName: require('templates/login')
+  templateName: require('templates/login'),
+  passTextField : Em.TextField.extend({
+    insertNewline: function(){
+      this.get("controller").submit();
+    }
+  })
 
 
 });
 });

+ 3 - 3
ambari-web/app/views/main/apps/item/bar_view.js

@@ -33,15 +33,15 @@ App.MainAppsItemBarView = Em.View.extend({
         this.set('activeJob', event.context);
         this.set('activeJob', event.context);
 
 
     },
     },
-    didInsertElement:function (){
+    didInsertElement:function () {
         this.set('activeJob', this.get('firstJob'));
         this.set('activeJob', this.get('firstJob'));
     },
     },
     draw: function() {
     draw: function() {
         if(!this.get('activeJob')){
         if(!this.get('activeJob')){
             return;//when job is not defined
             return;//when job is not defined
         }
         }
-        width = 500;
-        height = 420;
+        width = 300;
+        height = 210;
         var desc1 = $('#graph1_desc');
         var desc1 = $('#graph1_desc');
         var desc2 = $('#graph2_desc');
         var desc2 = $('#graph2_desc');
         $('.rickshaw_graph, .rickshaw_legend, .rickshaw_annotation_timeline').html('');
         $('.rickshaw_graph, .rickshaw_legend, .rickshaw_annotation_timeline').html('');

+ 12 - 2
ambari-web/app/views/main/apps/item/dag_view.js

@@ -60,12 +60,22 @@ App.MainAppsItemDagView = Em.View.extend({
         }
         }
       },
       },
       "iDisplayLength": 5,
       "iDisplayLength": 5,
-      "aLengthMenu": [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]]
+      "aLengthMenu": [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]],
+      "aoColumns":[
+        null,
+        null,
+        null,
+        null,
+        null,
+        { "sType":"ambari-bandwidth" },
+        { "sType":"ambari-bandwidth" },
+        null
+      ]
     });
     });
     var dagSchema = this.get('parentView.parentView.content').get('workflowContext');
     var dagSchema = this.get('parentView.parentView.content').get('workflowContext');
     var jobs = this.get('jobs');
     var jobs = this.get('jobs');
     var graph = new DagViewer(false, 'dag_viewer')
     var graph = new DagViewer(false, 'dag_viewer')
-        .setPhysicalParametrs(800, 250, -800, 0.01)
+        .setPhysicalParametrs(800, 300, -800, 0.01)
         .setData(dagSchema, jobs)
         .setData(dagSchema, jobs)
         .drawDag(10, 20, 100);
         .drawDag(10, 20, 100);
   }
   }

+ 127 - 37
ambari-web/app/views/main/apps_view.js

@@ -19,6 +19,7 @@
 var App = require('app');
 var App = require('app');
 var date = require('utils/date');
 var date = require('utils/date');
 var validator = require('utils/validator');
 var validator = require('utils/validator');
+var misc = require('utils/misc');
 
 
 App.MainAppsView = Em.View.extend({
 App.MainAppsView = Em.View.extend({
   templateName:require('templates/main/apps'),
   templateName:require('templates/main/apps'),
@@ -31,10 +32,6 @@ App.MainAppsView = Em.View.extend({
       var app = App.store.find(App.App, run.get('appId'));
       var app = App.store.find(App.App, run.get('appId'));
       run.set('appName', app.get('appName'));
       run.set('appName', app.get('appName'));
       run.set('type', app.get('type'));
       run.set('type', app.get('type'));
-      run.set('numJobsTotal' ,run.get('jobs').get('content').length);
-      run.get('jobs').forEach(function(job) {
-
-      });
     });
     });
     return content;
     return content;
   }.property('App.router.mainAppsController.content'),
   }.property('App.router.mainAppsController.content'),
@@ -46,7 +43,7 @@ App.MainAppsView = Em.View.extend({
    * starred - show only filtered runs with stars selected
    * starred - show only filtered runs with stars selected
    */
    */
   viewType : 'all',
   viewType : 'all',
-
+  defaultViewType: 'all',
   /**
   /**
    * List of users
    * List of users
    */
    */
@@ -174,6 +171,12 @@ App.MainAppsView = Em.View.extend({
     else {
     else {
       youngest = '0000-00-00';
       youngest = '0000-00-00';
     }
     }
+    avgInput = misc.formatBandwidth(avgInput);
+    minInput = misc.formatBandwidth(minInput);
+    maxInput = misc.formatBandwidth(maxInput);
+    avgOutput = misc.formatBandwidth(avgOutput);
+    minOutput = misc.formatBandwidth(minOutput);
+    maxOutput = misc.formatBandwidth(maxOutput);
     ret = {
     ret = {
       'count': this.get('controller.staredRuns').length,
       'count': this.get('controller.staredRuns').length,
       'jobs': {
       'jobs': {
@@ -182,12 +185,12 @@ App.MainAppsView = Em.View.extend({
         'max': maxJobs
         'max': maxJobs
       },
       },
       'input': {
       'input': {
-        'avg': avgInput.toFixed(2),
+        'avg': avgInput,
         'min': minInput,
         'min': minInput,
         'max': maxInput
         'max': maxInput
       },
       },
       'output': {
       'output': {
-        'avg': avgOutput.toFixed(2),
+        'avg': avgOutput,
         'min': minOutput,
         'min': minOutput,
         'max': maxOutput
         'max': maxOutput
       },
       },
@@ -207,17 +210,58 @@ App.MainAppsView = Em.View.extend({
    * Click on big star on the avg block
    * Click on big star on the avg block
    */
    */
   avgStarClick: function() {
   avgStarClick: function() {
+    if (this.get('viewType') === 'starred') return;
     this.set('whatAvgShow', !this.get('whatAvgShow'));
     this.set('whatAvgShow', !this.get('whatAvgShow'));
     $('a.icon-star.a').toggleClass('active');
     $('a.icon-star.a').toggleClass('active');
   },
   },
+  starClicked: function() {
+    var runIndex = this.get('controller.lastStarClicked');
+    if (runIndex < 0) return;
+    if (!this.get('oTable')) return;
+    var rowIndex = -1;
+    // Get real row index
+    var column = this.get('oTable').fnGetColumnData(0);
+    for (var i = 0; i < column.length; i++) {
+      if (runIndex == $(column[i]).text()) {
+        rowIndex = i;
+        break;
+      }
+    }
+    var perPage = this.get('oTable').fnSettings()['_iDisplayLength']; // How many rows show per page
+    var rowIndexVisible = rowIndex; // rowIndexVisible - rowIndex in current visible part of the table
+    if (perPage !== -1) { // If not show All is selected we should recalculate row index according to other visible rows
+      rowIndexVisible = rowIndex % perPage;
+    }
+    // Update inner dataTable value
+    this.get('oTable').fnUpdate( $('#dataTable tbody tr:eq(' + rowIndexVisible + ') td:eq(0)').html(), this.get('oTable').fnSettings()['aiDisplay'][rowIndex], 0);
+    if (perPage !== -1) { // Change page after reDraw (if show All is selected this will not happens)
+      this.get('oTable').fnPageChange(Math.floor(rowIndex / perPage));
+    }
+  }.observes('controller.lastStarClicked'),
   /**
   /**
-   * "turn off" stars in the table
+   * Flush all starred runs
    */
    */
   clearStars: function() {
   clearStars: function() {
+    this.get('controller').set('staredRuns', []);
+    this.get('controller').set('staredRunsLength', 0);
+    this.set('viewType', this.get('defaultViewType'));
+    this.set('whatAvgShow', true);
+    $('a.icon-star.a').removeClass('active');
+  },
+  /**
+   * "turn off" stars in the table
+   */
+  resetStars: function() {
+    var self = this;
     if (this.get('controller.staredRunsLength') == 0 && this.get('smallStarsIcons') != null) {
     if (this.get('controller.staredRunsLength') == 0 && this.get('smallStarsIcons') != null) {
       this.get('smallStarsIcons').removeClass('stared');
       this.get('smallStarsIcons').removeClass('stared');
-      this.set('whatAvgShow', true);
+      $('#dataTable .icon-star').removeClass('stared');
       $('a.icon-star.a').removeClass('active');
       $('a.icon-star.a').removeClass('active');
+      this.get('starFilterViewInstance').set('value', '');
+      $('#dataTable tbody tr').each(function(index) {
+        var td = $(this).find('td:eq(0)');
+        self.get('oTable').fnUpdate( td.html(), index, 0);
+      });
     }
     }
   }.observes('controller.staredRunsLength'),
   }.observes('controller.staredRunsLength'),
   /**
   /**
@@ -227,49 +271,71 @@ App.MainAppsView = Em.View.extend({
     this.clearFilters();
     this.clearFilters();
     this.clearStars();
     this.clearStars();
   },
   },
-
+  /**
+   * Display only stared rows
+   */
+  showStared: function() {
+    this.get('starFilterViewInstance').set('value', 'stared');
+    this.set('whatAvgShow', false);
+    $('a.icon-star.a').addClass('active');
+  },
   /**
   /**
    * Onclick handler for <code>Show All/Filtered/Starred</code> links
    * Onclick handler for <code>Show All/Filtered/Starred</code> links
    */
    */
-  changeViewType: function(event){
-    if($(event.toElement).hasClass('selected')){
-      return;
-    }
-
-    $(event.toElement).parent().children('.selected').removeClass('selected');
-    $(event.toElement).addClass('selected');
-
-    var viewType = $(event.toElement).data('view-type');
+  clickViewType: function(event) {
+    this.set('viewType', $(event.target).data('view-type'));
+  },
+  onChangeViewType: function(){
+    var viewType = this.get('viewType');
+    var table = this.get('oTable');
+    var filterButtons = $("#filter_buttons").children();
+    filterButtons.each(function(index, element){
+      $(element).removeClass('selected');
+      if(viewType == $(element).data('view-type')){
+        $(element).addClass('selected');
+      }
+    });
     console.log(viewType);
     console.log(viewType);
-
-    switch(viewType){
+    switch(viewType) {
       case 'all':
       case 'all':
-        //do stuff here
+        table.fnSettings().oFeatures.bFilter = false;
+        table.fnDraw();
+        table.fnSettings().oFeatures.bFilter = true;
         break;
         break;
-
       case 'starred':
       case 'starred':
+        this.showStared();
         break;
         break;
-
       case 'filtered':
       case 'filtered':
-      default:
-        //do stuff here
+        table.fnSettings().oFeatures.bFilter = true;
+        table.fnDraw();
         break;
         break;
-    };
+      };
 
 
-  },
+
+  }.observes('viewType'),
 
 
   /**
   /**
    * jQuery dataTable init
    * jQuery dataTable init
    */
    */
-  didInsertElement:function () {
+  createDataTable: function () {
     var smallStars = $('#dataTable .icon-star');
     var smallStars = $('#dataTable .icon-star');
+    var self = this;
     this.set('smallStarsIcons', smallStars);
     this.set('smallStarsIcons', smallStars);
     var oTable = this.$('#dataTable').dataTable({
     var oTable = this.$('#dataTable').dataTable({
       "sDom": '<"search-bar"f><"clear">rt<"page-bar"lip><"clear">',
       "sDom": '<"search-bar"f><"clear">rt<"page-bar"lip><"clear">',
       "fnDrawCallback": function( oSettings ) {
       "fnDrawCallback": function( oSettings ) {
-        //change average info after table filtering
-        // no need more. 31.10.2012
+        if(!self.get('oTable')){return}
+        if(self.get('viewType') !== 'all') {
+          if (self.get('viewType') !== 'starred') {
+            self.set('filtered', this.fnSettings().fnRecordsDisplay());
+          }
+        }
+        if(self.get('viewType') === 'all' && self.get('oTable').fnSettings().oFeatures.bFilter){
+          self.set('viewType', 'filtered');
+          self.set('filtered', this.fnSettings().fnRecordsDisplay());
+        }
       },
       },
+      "aaSorting": [],
       "oLanguage": {
       "oLanguage": {
         "sSearch": "Search:",
         "sSearch": "Search:",
         "sLengthMenu": "Show: _MENU_",
         "sLengthMenu": "Show: _MENU_",
@@ -291,8 +357,8 @@ App.MainAppsView = Em.View.extend({
         null,
         null,
         null,
         null,
         null,
         null,
-        null,
-        null,
+        { "sType":"ambari-bandwidth" },
+        { "sType":"ambari-bandwidth" },
         null,
         null,
         { "sType":"ambari-date" }
         { "sType":"ambari-date" }
       ]
       ]
@@ -301,6 +367,17 @@ App.MainAppsView = Em.View.extend({
     this.set('filtered', oTable.fnSettings().fnRecordsDisplay());
     this.set('filtered', oTable.fnSettings().fnRecordsDisplay());
 
 
   },
   },
+  didInsertElement: function () {
+    var self = this;
+    /**
+     * Running datatable with delay to take time to load all data
+     */
+    Ember.run.next(function () {
+      Ember.run.next(function () {
+        self.createDataTable();
+      })
+    });
+  },
   /**
   /**
    * reset all filters in dataTable
    * reset all filters in dataTable
    *
    *
@@ -319,6 +396,7 @@ App.MainAppsView = Em.View.extend({
     }
     }
     });
     });
     this.get('oTable').fnFilterClear();
     this.get('oTable').fnFilterClear();
+    this.set('viewType', this.get('defaultViewType'));
     this.set('filtered',this.get('oTable').fnSettings().fnRecordsDisplay());
     this.set('filtered',this.get('oTable').fnSettings().fnRecordsDisplay());
     this.setFilteredRuns(this.get('oTable')._('tr', {"filter":"applied"}));
     this.setFilteredRuns(this.get('oTable')._('tr', {"filter":"applied"}));
   },
   },
@@ -332,8 +410,8 @@ App.MainAppsView = Em.View.extend({
   applyFilter:function(parentView, iColumn, value) {
   applyFilter:function(parentView, iColumn, value) {
       value = (value) ? value : '';
       value = (value) ? value : '';
       parentView.get('oTable').fnFilter(value, iColumn);
       parentView.get('oTable').fnFilter(value, iColumn);
-      parentView.set('filtered',parentView.get('oTable').fnSettings().fnRecordsDisplay());
   },
   },
+
   /**
   /**
    * refresh average info in top block when filtered changes
    * refresh average info in top block when filtered changes
    */
    */
@@ -353,11 +431,11 @@ App.MainAppsView = Em.View.extend({
     content:['Any', 'Pig', 'Hive', 'mapReduce'],
     content:['Any', 'Pig', 'Hive', 'mapReduce'],
     change:function(event){
     change:function(event){
       if(this.get('selection') === 'Any') {
       if(this.get('selection') === 'Any') {
-        this._parentView.get('oTable').fnFilter('', 3);
+        this.get('parentView').get('oTable').fnFilter('', 3);
       } else {
       } else {
-      this._parentView.get('oTable').fnFilter(this.get('selection'), 3);
+      this.get('parentView').get('oTable').fnFilter(this.get('selection'), 3);
       }
       }
-      this._parentView.set('filtered',this._parentView.get('oTable').fnSettings().fnRecordsDisplay());
+      this.get('parentView').set('filtered',this.get('parentView').get('oTable').fnSettings().fnRecordsDisplay());
     }
     }
   }),
   }),
   /**
   /**
@@ -375,6 +453,18 @@ App.MainAppsView = Em.View.extend({
       this.get('parentView').get('applyFilter')(this.get('parentView'), 9);
       this.get('parentView').get('applyFilter')(this.get('parentView'), 9);
     }
     }
   }),
   }),
+  /**
+   * Filter-field for Stars. hidden
+   */
+  starFilterView: Em.TextField.extend({
+    classNames:['input-small'],
+    type:'hidden',
+    placeholder: '',
+    elementId:'star_filter',
+    filtering:function() {
+      this.get('parentView').get('applyFilter')(this.get('parentView'), 0);
+    }.observes('value')
+  }),
   /**
   /**
    * Filter-field for AppId
    * Filter-field for AppId
    */
    */

+ 23 - 27
ambari-web/app/views/main/dashboard/service.js

@@ -21,33 +21,33 @@ var App = require('app');
 require('models/alert');
 require('models/alert');
 
 
 App.MainDashboardServiceHealthView = Em.View.extend({
 App.MainDashboardServiceHealthView = Em.View.extend({
-  classNameBindings:["healthStatus"],
-  template:Em.Handlebars.compile(""),
-  blink:false,
+  classNameBindings: ["healthStatus"],
+  template: Em.Handlebars.compile(""),
+  blink: false,
   tagName: 'span',
   tagName: 'span',
 
 
-  status:function () {
+  status: function () {
     return this.get('service.healthStatus');
     return this.get('service.healthStatus');
   }.property('service.healthStatus'),
   }.property('service.healthStatus'),
 
 
-  startBlink:function () {
+  startBlink: function () {
     this.set('blink', true);
     this.set('blink', true);
   },
   },
 
 
-  doBlink:function () {
+  doBlink: function () {
     if (this.get('blink') && (this.get("state") == "inDOM")) {
     if (this.get('blink') && (this.get("state") == "inDOM")) {
-      this.$().effect("pulsate", { times:1 }, "slow", function () {
+      this.$().effect("pulsate", { times: 1 }, "slow", function () {
         var view = Em.View.views[$(this).attr('id')];
         var view = Em.View.views[$(this).attr('id')];
         view.doBlink();
         view.doBlink();
       });
       });
     }
     }
   }.observes('blink'),
   }.observes('blink'),
 
 
-  stopBlink:function () {
+  stopBlink: function () {
     this.set('blink', false);
     this.set('blink', false);
   },
   },
 
 
-  healthStatus:function () {
+  healthStatus: function () {
     var status = this.get('status');
     var status = this.get('status');
     switch (status) {
     switch (status) {
       case App.Service.Health.start:
       case App.Service.Health.start:
@@ -66,40 +66,36 @@ App.MainDashboardServiceHealthView = Em.View.extend({
     return 'health-status-' + status + " span";
     return 'health-status-' + status + " span";
   }.property('status'),
   }.property('status'),
 
 
-  didInsertElement:function () {
+  didInsertElement: function () {
     this._super();
     this._super();
     this.doBlink(); // check for blink availability
     this.doBlink(); // check for blink availability
   }
   }
 });
 });
 
 
 App.MainDashboardServiceView = Em.View.extend({
 App.MainDashboardServiceView = Em.View.extend({
-  classNames:['service', 'clearfix'],
-  data:function () {
+  classNames: ['service', 'clearfix'],
+
+  data: function () {
     return this.get('controller.data.' + this.get('serviceName'));
     return this.get('controller.data.' + this.get('serviceName'));
   }.property('controller.data'),
   }.property('controller.data'),
-  service:function () {
+
+  service: function () {
     var services = this.get('controller.services');
     var services = this.get('controller.services');
     if (services) {
     if (services) {
-      thisView = this;
-      var serviceProperty = false;
-      services.forEach(function (service) {
-        if (service.get('serviceName') == thisView.get('serviceName')) {
-          return serviceProperty = service;
-        }
-      })
+      return services.findProperty('serviceName', this.get('serviceName'));
     }
     }
-
-    return serviceProperty;
   }.property('controller.services'),
   }.property('controller.services'),
 
 
-  criticalAlertsCount:function () {
+  criticalAlertsCount: function () {
     var alerts = this.get('service.alerts');
     var alerts = this.get('service.alerts');
     var count = 0;
     var count = 0;
 
 
-    alerts.forEach(function (alert) {
-      count += (alert.get('status') == App.AlertStatus.negative);
-    });
-
+    if (alerts) {
+      alerts.forEach(function (alert) {
+        count += (alert.get('status') == App.AlertStatus.negative);
+      });
+    }
     return count;
     return count;
   }.property('service.alerts')
   }.property('service.alerts')
+
 });
 });

+ 32 - 12
ambari-web/app/views/main/host.js

@@ -21,13 +21,13 @@ var App = require('app');
 App.MainHostView = Em.View.extend({
 App.MainHostView = Em.View.extend({
   templateName:require('templates/main/host'),
   templateName:require('templates/main/host'),
   filterByName:"",
   filterByName:"",
-  controller: function(){
+  controller:function () {
     return App.router.get('mainHostController');
     return App.router.get('mainHostController');
   }.property(),
   }.property(),
   content:function () {
   content:function () {
     return App.router.get('mainHostController.content');
     return App.router.get('mainHostController.content');
   }.property('App.router.mainHostController.content'),
   }.property('App.router.mainHostController.content'),
-  componentsIds: [1, 2, 3, 4, 5, 6, 7, 8],
+  componentsIds:[1, 2, 3, 4, 5, 6, 7, 8],
 
 
   isFilterOpen:false,
   isFilterOpen:false,
 
 
@@ -45,29 +45,29 @@ App.MainHostView = Em.View.extend({
     App.router.get('mainHostController').filterByComponentsIds();
     App.router.get('mainHostController').filterByComponentsIds();
   },
   },
 
 
-  allComponentsChecked: false,
-  toggleAllComponents: function(){
+  allComponentsChecked:false,
+  toggleAllComponents:function () {
     this.set('masterComponentsChecked', this.get('allComponentsChecked'));
     this.set('masterComponentsChecked', this.get('allComponentsChecked'));
     this.set('slaveComponentsChecked', this.get('allComponentsChecked'));
     this.set('slaveComponentsChecked', this.get('allComponentsChecked'));
   }.observes('allComponentsChecked'),
   }.observes('allComponentsChecked'),
 
 
-  masterComponentsChecked: false,
-  toggleMasterComponents: function(){
+  masterComponentsChecked:false,
+  toggleMasterComponents:function () {
     var checked = this.get('masterComponentsChecked');
     var checked = this.get('masterComponentsChecked');
-    this.get('controller.masterComponents').forEach(function(comp){
+    this.get('controller.masterComponents').forEach(function (comp) {
       comp.set('checkedForHostFilter', checked);
       comp.set('checkedForHostFilter', checked);
     });
     });
   }.observes('masterComponentsChecked'),
   }.observes('masterComponentsChecked'),
 
 
-  slaveComponentsChecked: false,
-  toggleSlaveComponents: function(){
+  slaveComponentsChecked:false,
+  toggleSlaveComponents:function () {
     var checked = this.get('slaveComponentsChecked');
     var checked = this.get('slaveComponentsChecked');
-    this.get('controller.slaveComponents').forEach(function(comp){
+    this.get('controller.slaveComponents').forEach(function (comp) {
       comp.set('checkedForHostFilter', checked);
       comp.set('checkedForHostFilter', checked);
     });
     });
   }.observes('slaveComponentsChecked'),
   }.observes('slaveComponentsChecked'),
 
 
-  didInsertElement: function(){
+  didInsertElement:function () {
     this._super();
     this._super();
     this.set('allComponentsChecked', true); // select all components (checkboxes) on start.
     this.set('allComponentsChecked', true); // select all components (checkboxes) on start.
   },
   },
@@ -76,7 +76,7 @@ App.MainHostView = Em.View.extend({
     App.router.get('mainHostController').filterHostsBy('hostName', this.get('filterByName'));
     App.router.get('mainHostController').filterHostsBy('hostName', this.get('filterByName'));
   }.observes('filterByName'),
   }.observes('filterByName'),
 
 
-  closeFilters: function(){
+  closeFilters:function () {
     $(document).unbind('click');
     $(document).unbind('click');
     this.clickFilterButton();
     this.clickFilterButton();
   },
   },
@@ -124,5 +124,25 @@ App.MainHostView = Em.View.extend({
         App.router.get('mainHostController').onHostChecked(this.get('content'));
         App.router.get('mainHostController').onHostChecked(this.get('content'));
       }
       }
     })
     })
+  }),
+
+  RackCombobox:App.Combobox.extend({
+    disabled:function () {
+      var selectedHostsIds = App.router.get('mainHostController.selectedHostsIds');
+
+      // when user apply assigning and hosts become unchecked, we need to clear textfield
+      if (!selectedHostsIds.length) {
+        this.clearTextFieldValue();
+      }
+
+      return !selectedHostsIds.length;
+
+    }.property('App.router.mainHostController.selectedHostsIds'),
+
+    recordArray:App.Cluster.find(),
+    placeholderText:Em.I18n.t('hosts.assignRack'),
+    selectionBinding:"App.router.mainHostController.selectedRack",
+    optionLabelPath:"content.clusterName",
+    optionValuePath:"content.id"
   })
   })
 });
 });

+ 18 - 3
ambari-web/app/views/main/service/info/configs.js

@@ -20,7 +20,22 @@ var App = require('app');
 
 
 App.MainServiceInfoConfigsView = Em.View.extend({
 App.MainServiceInfoConfigsView = Em.View.extend({
   templateName: require('templates/main/service/info/configs'),
   templateName: require('templates/main/service/info/configs'),
-  alerts: function(){
-    return App.router.get('mainAlertController.content');
-  }.property('App.router.mainAlertController.content')
+  didInsertElement: function () {
+    var controller = this.get('controller');
+    controller.loadStep();
+  }
+});
+
+App.ServiceConfigsByCategoryView = Ember.View.extend({
+
+  content: null,
+
+  category: null,
+  serviceConfigs: null, // General, Advanced, NameNode, SNameNode, DataNode, etc.
+
+  categoryConfigs: function () {
+    return this.get('serviceConfigs').filterProperty('category', this.get('category.name'))
+  }.property('serviceConfigs.@each').cacheable(),
+
+  layout: Ember.Handlebars.compile('<div class="accordion-body collapse in"><div class="accordion-inner">{{yield}}</div></div>')
 });
 });

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

@@ -23,12 +23,22 @@ App.MainServiceInfoSummaryView = Em.View.extend({
   serviceStatus: {
   serviceStatus: {
     hdfs: false,
     hdfs: false,
     mapreduce: false,
     mapreduce: false,
-    hbase: false
+    hbase: false,
+    zookeeper: false,
+    oozie: false,
+    hive: false
   },
   },
+
   controller: function () {
   controller: function () {
     return App.router.get('mainServiceInfoSummaryController');
     return App.router.get('mainServiceInfoSummaryController');
   }.property(),
   }.property(),
-
+  data:{
+    hive:{
+      "database"     : "PostgreSQL",
+      "databaseName" : "hive",
+      "user"         : "hive"
+    }
+  },
   service: function () {
   service: function () {
     return this.get('controller.content');
     return this.get('controller.content');
   }.property('controller.content'),
   }.property('controller.content'),

+ 24 - 0
ambari-web/app/views/main/test.js

@@ -0,0 +1,24 @@
+/**
+ * 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.MainTestView = Em.View.extend({
+  templateName: require('templates/main/test'),
+  services: App.Service1.find()
+});

+ 39 - 1
ambari-web/app/views/wizard/step2_view.js

@@ -19,6 +19,27 @@
 
 
 var App = require('app');
 var App = require('app');
 
 
+App.SshKeyFileUploader = Ember.View.extend({
+  template:Ember.Handlebars.compile('<input type="file" />'),
+
+  change: function (e) {
+    self=this;
+    if (e.target.files && e.target.files.length == 1) {
+      var file = e.target.files[0];
+      var reader = new FileReader();
+
+      reader.onload = (function(theFile) {
+        return function(e) {
+          $('#sshKey').html(e.target.result);
+          //$('.sshKey-file-view').html(e.target.result);
+          self.set("controller.content.sshKey", e.target.result);
+        };
+      })(file);
+      reader.readAsText(file);
+    }
+  }
+});
+
 App.WizardStep2View = Em.View.extend({
 App.WizardStep2View = Em.View.extend({
 
 
   templateName: require('templates/wizard/step2'),
   templateName: require('templates/wizard/step2'),
@@ -38,7 +59,24 @@ App.WizardStep2View = Em.View.extend({
     } else {
     } else {
       this.set('hostNameErr', true);
       this.set('hostNameErr', true);
     }
     }
-  }.observes('controller.hostNameEmptyError', 'controller.hostNameNotRequiredErr', 'controller.hostNameErr')
+  }.observes('controller.hostNameEmptyError', 'controller.hostNameNotRequiredErr', 'controller.hostNameErr'),
+
+  sshKeyState: function(){
+    return this.get("controller").get("content.manualInstall");
+  }.property("controller.content.manualInstall"),
+
+  sshKeyClass:function() {
+    //alert(this.get("isFileApi"))
+    return (this.get("isFileApi")) ? "hide" : "" ;
+  }.property("isFileApi"),
+
+  isFileApi: function () {
+    return (window.File && window.FileReader && window.FileList) ? true : false ;
+  }.property(),
+
+  sshKeyPreviewClass: function() {
+    return (this.get('controller.content.sshKey').trim() != '') ? 'sshKey-file-view help-inline' : 'hidden';
+  }.property('controller.content.sshKey')
 
 
 });
 });
 
 

+ 2 - 0
ambari-web/config.coffee

@@ -39,6 +39,7 @@ exports.config =
           'vendor/scripts/ember-data-latest.js',
           'vendor/scripts/ember-data-latest.js',
           'vendor/scripts/ember-i18n-1.2.0.js',
           'vendor/scripts/ember-i18n-1.2.0.js',
           'vendor/scripts/bootstrap.js',
           'vendor/scripts/bootstrap.js',
+          'vendor/scripts/bootstrap-combobox.js'
           'vendor/scripts/d3.v2.js',
           'vendor/scripts/d3.v2.js',
           'vendor/scripts/sinon-1.4.2.js',
           'vendor/scripts/sinon-1.4.2.js',
           'vendor/scripts/cubism.v1.js',
           'vendor/scripts/cubism.v1.js',
@@ -66,6 +67,7 @@ exports.config =
           'vendor/styles/font-awesome-ie7.css',
           'vendor/styles/font-awesome-ie7.css',
           'vendor/styles/cubism.css',
           'vendor/styles/cubism.css',
           'vendor/styles/rickshaw.css'
           'vendor/styles/rickshaw.css'
+          'vendor/styles/bootstrap-combobox.css'
         ]
         ]
 
 
     templates:
     templates:

+ 1 - 2
ambari-web/package.json

@@ -19,8 +19,7 @@
     "uglify-js-brunch": ">= 1.0 < 1.5",
     "uglify-js-brunch": ">= 1.0 < 1.5",
     "clean-css-brunch": ">= 1.0 < 1.5",
     "clean-css-brunch": ">= 1.0 < 1.5",
     "ember-handlebars-brunch": "git://github.com/icholy/ember-handlebars-brunch.git",
     "ember-handlebars-brunch": "git://github.com/icholy/ember-handlebars-brunch.git",
-    "less-brunch": "git://github.com/brunch/less-brunch.git",
-    "d3": ">=2.10.3"
+    "less-brunch": "git://github.com/brunch/less-brunch.git"
   },
   },
   "devDependencies": {
   "devDependencies": {
     "mocha": "0.14.0",
     "mocha": "0.14.0",

+ 1 - 1
ambari-web/pom.xml

@@ -16,7 +16,7 @@
   <artifactId>ambari-web</artifactId>
   <artifactId>ambari-web</artifactId>
   <packaging>pom</packaging>
   <packaging>pom</packaging>
   <name>Ambari Web</name>
   <name>Ambari Web</name>
-  <version>1.0.3-SNAPSHOT</version>
+  <version>1.0.3</version>
   <description>Ambari Web</description>
   <description>Ambari Web</description>
   <dependencies>
   <dependencies>
     <dependency>
     <dependency>

+ 217 - 0
ambari-web/vendor/scripts/bootstrap-combobox.js

@@ -0,0 +1,217 @@
+/* =============================================================
+ * bootstrap-combobox.js v1.0.0
+ * =============================================================
+ * Copyright 2012 Daniel Farrell
+ *
+ * Licensed 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.
+ * ============================================================ */
+
+!function ($) {
+
+  "use strict"
+
+  var Combobox = function (element, options) {
+    this.options = $.extend({}, $.fn.combobox.defaults, options)
+    this.$container = this.setup(element)
+    this.$element = this.$container.find('input')
+    this.$button = this.$container.find('.dropdown-toggle')
+    this.$target = this.$container.find('select')
+    this.matcher = this.options.matcher || this.matcher
+    this.sorter = this.options.sorter || this.sorter
+    this.highlighter = this.options.highlighter || this.highlighter
+    this.$menu = $(this.options.menu).appendTo('body')
+    this.placeholder = this.options.placeholder || this.$target.attr('data-placeholder')
+    this.$element.attr('placeholder', this.placeholder)
+    this.shown = false
+    this.selected = false
+    this.refresh()
+    this.listen()
+  }
+
+  /* NOTE: COMBOBOX EXTENDS BOOTSTRAP-TYPEAHEAD.js
+   ========================================== */
+
+  Combobox.prototype = $.extend({}, $.fn.typeahead.Constructor.prototype, {
+
+    constructor:Combobox, setup:function (element) {
+      var select = $(element)
+        , combobox = $(this.options.template)
+      select.before(combobox)
+      select.detach()
+      combobox.append(select)
+      return combobox
+    },
+    parse:function () {
+      var map = {}
+        , source = []
+        , selected = false
+      this.$target.find('option').each(function () {
+        var option = $(this)
+        map[option.text()] = option.val()
+        source.push(option.text())
+        if (option.attr('selected')) selected = option.html()
+      })
+      this.map = map
+      if (selected) {
+        this.$element.val(selected)
+        this.$container.addClass('combobox-selected')
+        this.selected = true
+      }
+      return source
+    },
+    toggle:function () {
+      if (this.$container.hasClass('combobox-selected')) {
+        this.clearTarget()
+        this.$element.val('').focus()
+      } else {
+        if (this.shown) {
+          this.hide()
+        } else {
+          this.lookup()
+        }
+      }
+    },
+    clearTarget:function () {
+      this.$target.val('')
+      this.$container.removeClass('combobox-selected')
+      this.selected = false
+      this.$target.trigger('change')
+    },
+    refresh:function () {
+      this.source = this.parse()
+      this.options.items = this.source.length
+    }
+
+    // modified typeahead function adding container and target handling
+    , select:function () {
+      var val = this.$menu.find('.active').attr('data-value')
+      this.$element.val(val)
+      this.$container.addClass('combobox-selected')
+      this.$target.val(this.map[val])
+      this.$target.trigger('change')
+      this.selected = true
+      return this.hide()
+    }
+
+    // modified typeahead function removing the blank handling
+    , lookup:function (event) {
+      var that = this
+        , items
+        , q
+
+      this.query = this.$element.val()
+
+      items = $.grep(this.source, function (item) {
+        if (that.matcher(item)) return item
+      })
+
+      items = this.sorter(items)
+
+      if (!items.length) {
+        return this.shown ? this.hide() : this
+      }
+
+      return this.render(items.slice(0, this.options.items)).show()
+    }
+
+    // modified typeahead function adding button handling
+    , listen:function () {
+      this.$element
+        .on('blur', $.proxy(this.blur, this))
+        .on('keypress', $.proxy(this.keypress, this))
+        .on('keyup', $.proxy(this.keyup, this))
+
+      if ($.browser.webkit || $.browser.msie) {
+        this.$element.on('keydown', $.proxy(this.keypress, this))
+      }
+
+      this.$menu
+        .on('click', $.proxy(this.click, this))
+        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
+
+      this.$button
+        .on('click', $.proxy(this.toggle, this))
+    }
+
+    // modified typeahead function to clear on type and prevent on moving around
+    , keyup:function (e) {
+      switch (e.keyCode) {
+        case 40: // down arrow
+        case 39: // right arrow
+        case 38: // up arrow
+        case 37: // left arrow
+        case 36: // home
+        case 35: // end
+        case 16: // shift
+          break
+
+        case 9: // tab
+        case 13: // enter
+          if (!this.shown) return
+          this.select()
+          break
+
+        case 27: // escape
+          if (!this.shown) return
+          this.hide()
+          break
+
+        default:
+          this.clearTarget()
+          this.lookup()
+      }
+
+      e.stopPropagation()
+      e.preventDefault()
+    }
+
+    // modified typeahead function to only hide menu if it is visible
+    , blur:function (e) {
+      var that = this
+      e.stopPropagation()
+      e.preventDefault()
+      var val = this.$element.val()
+      if (!this.selected && val != "") {
+        this.$element.val("")
+        this.$target.val("").trigger('change')
+      }
+      if (this.shown) {
+        setTimeout(function () {
+          that.hide()
+        }, 150)
+      }
+    }
+  })
+
+  /* COMBOBOX PLUGIN DEFINITION
+   * =========================== */
+
+  $.fn.combobox = function (option) {
+    return this.each(function () {
+      var $this = $(this)
+        , data = $this.data('combobox')
+        , options = typeof option == 'object' && option
+      if (!data) $this.data('combobox', (data = new Combobox(this, options)))
+      if (typeof option == 'string') data[option]()
+    })
+  }
+
+  $.fn.combobox.defaults = {
+    template:'<div class="combobox-container"><input type="text" autocomplete="off" /><button class="add-on btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"/><span class="combobox-clear"><i class="icon-remove"/></span></button></div>',
+    menu:'<ul class="typeahead typeahead-long dropdown-menu"></ul>',
+    item:'<li><a href="#"></a></li>', placeholder:null
+  }
+
+  $.fn.combobox.Constructor = Combobox
+
+}(window.jQuery);

+ 53 - 53
ambari-web/vendor/scripts/jquery.dataTables.js

@@ -745,7 +745,7 @@
             };
             };
           }
           }
           else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1)) {
           else if (typeof mSource === 'string' && (mSource.indexOf('.') !== -1 || mSource.indexOf('[') !== -1)) {
-            /* If there is a . in the source string then the data source is in a 
+            /* If there is a . in the source string then the data source is in a
              * nested object so we loop over the data for each level to get the next
              * nested object so we loop over the data for each level to get the next
              * level down. On each loop we test for undefined, and if found immediately
              * level down. On each loop we test for undefined, and if found immediately
              * return. This allows entire objects to be missing and sDefaultContent to
              * return. This allows entire objects to be missing and sDefaultContent to
@@ -1336,9 +1336,9 @@
           _fnCallbackFire(oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
           _fnCallbackFire(oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
             _fnGetDataMaster(oSettings), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ]);
             _fnGetDataMaster(oSettings), oSettings._iDisplayStart, oSettings.fnDisplayEnd(), oSettings.aiDisplay ]);
 
 
-          /* 
+          /*
            * Need to remove any old row from the display - note we can't just empty the tbody using
            * Need to remove any old row from the display - note we can't just empty the tbody using
-           * $().html('') since this will unbind the jQuery event handlers (even although the node 
+           * $().html('') since this will unbind the jQuery event handlers (even although the node
            * still exists!) - equally we can't use innerHTML, since IE throws an exception.
            * still exists!) - equally we can't use innerHTML, since IE throws an exception.
            */
            */
           var
           var
@@ -1422,7 +1422,7 @@
           var nHolding = $('<div></div>')[0];
           var nHolding = $('<div></div>')[0];
           oSettings.nTable.parentNode.insertBefore(nHolding, oSettings.nTable);
           oSettings.nTable.parentNode.insertBefore(nHolding, oSettings.nTable);
 
 
-          /* 
+          /*
            * All DataTables are wrapped in a div
            * All DataTables are wrapped in a div
            */
            */
           oSettings.nTableWrapper = $('<div id="' + oSettings.sTableId + '_wrapper" class="' + oSettings.oClasses.sWrapper + '" role="grid"></div>')[0];
           oSettings.nTableWrapper = $('<div id="' + oSettings.sTableId + '_wrapper" class="' + oSettings.oClasses.sWrapper + '" role="grid"></div>')[0];
@@ -1590,7 +1590,7 @@
                 iColspan = (!iColspan || iColspan === 0 || iColspan === 1) ? 1 : iColspan;
                 iColspan = (!iColspan || iColspan === 0 || iColspan === 1) ? 1 : iColspan;
                 iRowspan = (!iRowspan || iRowspan === 0 || iRowspan === 1) ? 1 : iRowspan;
                 iRowspan = (!iRowspan || iRowspan === 0 || iRowspan === 1) ? 1 : iRowspan;
 
 
-                /* There might be colspan cells already in this row, so shift our target 
+                /* There might be colspan cells already in this row, so shift our target
                  * accordingly
                  * accordingly
                  */
                  */
                 iColShifted = fnShiftCol(aLayout, i, iColumn);
                 iColShifted = fnShiftCol(aLayout, i, iColumn);
@@ -2015,7 +2015,7 @@
           }
           }
           else {
           else {
             /*
             /*
-             * We are starting a new search or the new search string is smaller 
+             * We are starting a new search or the new search string is smaller
              * then the old one (i.e. delete). Search from the master array
              * then the old one (i.e. delete). Search from the master array
              */
              */
             if (oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length ||
             if (oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length ||
@@ -2028,7 +2028,7 @@
               _fnBuildSearchArray(oSettings, 1);
               _fnBuildSearchArray(oSettings, 1);
 
 
               /* Search through all records to populate the search array
               /* Search through all records to populate the search array
-               * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 
+               * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1
                * mapping
                * mapping
                */
                */
               for (i = 0; i < oSettings.aiDisplayMaster.length; i++) {
               for (i = 0; i < oSettings.aiDisplayMaster.length; i++) {
@@ -2505,7 +2505,7 @@
 
 
 
 
         /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-         * Note that most of the paging logic is done in 
+         * Note that most of the paging logic is done in
          * DataTable.ext.oPagination
          * DataTable.ext.oPagination
          */
          */
 
 
@@ -2927,11 +2927,11 @@
            * set the width based on the real headers
            * set the width based on the real headers
            */
            */
 
 
-          // Apply all styles in one pass. Invalidates layout only once because we don't read any 
+          // Apply all styles in one pass. Invalidates layout only once because we don't read any
           // DOM properties.
           // DOM properties.
           _fnApplyToChildren(zeroOut, anHeadSizers);
           _fnApplyToChildren(zeroOut, anHeadSizers);
 
 
-          // Read all widths in next pass. Forces layout only once because we do not change 
+          // Read all widths in next pass. Forces layout only once because we do not change
           // any DOM properties.
           // any DOM properties.
           _fnApplyToChildren(function (nSizer) {
           _fnApplyToChildren(function (nSizer) {
             aApplied.push(_fnStringToCss($(nSizer).width()));
             aApplied.push(_fnStringToCss($(nSizer).width()));
@@ -3165,8 +3165,8 @@
             }
             }
           }
           }
 
 
-          /* If the number of columns in the DOM equals the number that we have to process in 
-           * DataTables, then we can use the offsets that are created by the web-browser. No custom 
+          /* If the number of columns in the DOM equals the number that we have to process in
+           * DataTables, then we can use the offsets that are created by the web-browser. No custom
            * sizes can be set in order for this to happen, nor scrolling used
            * sizes can be set in order for this to happen, nor scrolling used
            */
            */
           if (iColums == oHeaders.length && iUserInputs === 0 && iVisibleColumns == iColums &&
           if (iColums == oHeaders.length && iUserInputs === 0 && iVisibleColumns == iColums &&
@@ -3275,7 +3275,7 @@
               oNodes = _fnGetUniqueThs(oSettings, $('thead', nCalcTmp)[0]);
               oNodes = _fnGetUniqueThs(oSettings, $('thead', nCalcTmp)[0]);
             }
             }
 
 
-            /* Browsers need a bit of a hand when a width is assigned to any columns when 
+            /* Browsers need a bit of a hand when a width is assigned to any columns when
              * x-scrolling as they tend to collapse the table to the min-width, even if
              * x-scrolling as they tend to collapse the table to the min-width, even if
              * we sent the column widths. So we need to keep track of what the table width
              * we sent the column widths. So we need to keep track of what the table width
              * should be by summing the user given values, and the automatic values
              * should be by summing the user given values, and the automatic values
@@ -3542,7 +3542,7 @@
              *  	return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
              *  	return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
              *  }
              *  }
              * Basically we have a test for each sorting column, if the data in that column is equal,
              * Basically we have a test for each sorting column, if the data in that column is equal,
-             * test the next column. If all columns match, then we use a numeric sort on the row 
+             * test the next column. If all columns match, then we use a numeric sort on the row
              * positions in the original data array to provide a stable sort.
              * positions in the original data array to provide a stable sort.
              */
              */
             oSettings.aiDisplayMaster.sort(function (a, b) {
             oSettings.aiDisplayMaster.sort(function (a, b) {
@@ -3635,14 +3635,14 @@
 
 
             /*
             /*
              * This is a little bit odd I admit... I declare a temporary function inside the scope of
              * This is a little bit odd I admit... I declare a temporary function inside the scope of
-             * _fnBuildHead and the click handler in order that the code presented here can be used 
-             * twice - once for when bProcessing is enabled, and another time for when it is 
+             * _fnBuildHead and the click handler in order that the code presented here can be used
+             * twice - once for when bProcessing is enabled, and another time for when it is
              * disabled, as we need to perform slightly different actions.
              * disabled, as we need to perform slightly different actions.
-             *   Basically the issue here is that the Javascript engine in modern browsers don't 
+             *   Basically the issue here is that the Javascript engine in modern browsers don't
              * appear to allow the rendering engine to update the display while it is still executing
              * appear to allow the rendering engine to update the display while it is still executing
-             * it's thread (well - it does but only after long intervals). This means that the 
+             * it's thread (well - it does but only after long intervals). This means that the
              * 'processing' display doesn't appear for a table sort. To break the js thread up a bit
              * 'processing' display doesn't appear for a table sort. To break the js thread up a bit
-             * I force an execution break by using setTimeout - but this breaks the expected 
+             * I force an execution break by using setTimeout - but this breaks the expected
              * thread continuation for the end-developer's point of view (their code would execute
              * thread continuation for the end-developer's point of view (their code would execute
              * too early), so we only do it when we absolutely have to.
              * too early), so we only do it when we absolutely have to.
              */
              */
@@ -3791,11 +3791,11 @@
             }
             }
           }
           }
 
 
-          /* 
+          /*
            * Apply the required classes to the table body
            * Apply the required classes to the table body
            * Note that this is given as a feature switch since it can significantly slow down a sort
            * Note that this is given as a feature switch since it can significantly slow down a sort
            * on large data sets (adding and removing of classes is always slow at the best of times..)
            * on large data sets (adding and removing of classes is always slow at the best of times..)
-           * Further to this, note that this code is admittedly fairly ugly. It could be made a lot 
+           * Further to this, note that this code is admittedly fairly ugly. It could be made a lot
            * simpler using jQuery selectors and add/removeClass, but that is significantly slower
            * simpler using jQuery selectors and add/removeClass, but that is significantly slower
            * (on the order of 5 times slower) - hence the direct DOM manipulation here.
            * (on the order of 5 times slower) - hence the direct DOM manipulation here.
            * Note that for deferred drawing we do use jQuery - the reason being that taking the first
            * Note that for deferred drawing we do use jQuery - the reason being that taking the first
@@ -3948,7 +3948,7 @@
           var date = new Date();
           var date = new Date();
           date.setTime(date.getTime() + (iSecs * 1000));
           date.setTime(date.getTime() + (iSecs * 1000));
 
 
-          /* 
+          /*
            * Shocking but true - it would appear IE has major issues with having the path not having
            * Shocking but true - it would appear IE has major issues with having the path not having
            * a trailing slash on it. We need the cookie to be available based on the path, so we
            * a trailing slash on it. We need the cookie to be available based on the path, so we
            * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the
            * have to append the file name to the cookie name. Appalling. Thanks to vex for adding the
@@ -4502,10 +4502,10 @@
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
 		 *
 		 *
-		 *      // Filter to 'Webkit' and get all data for 
+		 *      // Filter to 'Webkit' and get all data for
 		 *      oTable.fnFilter('Webkit');
 		 *      oTable.fnFilter('Webkit');
 		 *      var data = oTable._('tr', {"filter": "applied"});
 		 *      var data = oTable._('tr', {"filter": "applied"});
-		 *      
+		 *
 		 *      // Do something with the data
 		 *      // Do something with the data
 		 *      alert( data.length+" rows matched the filter" );
 		 *      alert( data.length+" rows matched the filter" );
 		 *    } );
 		 *    } );
@@ -4556,7 +4556,7 @@
 		 *        giCount+".3",
 		 *        giCount+".3",
 		 *        giCount+".4" ]
 		 *        giCount+".4" ]
 		 *      );
 		 *      );
-		 *        
+		 *
 		 *      giCount++;
 		 *      giCount++;
 		 *    }
 		 *    }
          */
          */
@@ -4612,7 +4612,7 @@
 		 *        "sScrollY": "200px",
 		 *        "sScrollY": "200px",
 		 *        "bPaginate": false
 		 *        "bPaginate": false
 		 *      } );
 		 *      } );
-		 *      
+		 *
 		 *      $(window).bind('resize', function () {
 		 *      $(window).bind('resize', function () {
 		 *        oTable.fnAdjustColumnSizing();
 		 *        oTable.fnAdjustColumnSizing();
 		 *      } );
 		 *      } );
@@ -4640,7 +4640,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
 		 *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
 		 *      oTable.fnClearTable();
 		 *      oTable.fnClearTable();
 		 *    } );
 		 *    } );
@@ -4666,7 +4666,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable;
 		 *      var oTable;
-		 *      
+		 *
 		 *      // 'open' an information row when a row is clicked on
 		 *      // 'open' an information row when a row is clicked on
 		 *      $('#example tbody tr').click( function () {
 		 *      $('#example tbody tr').click( function () {
 		 *        if ( oTable.fnIsOpen(this) ) {
 		 *        if ( oTable.fnIsOpen(this) ) {
@@ -4675,7 +4675,7 @@
 		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
 		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
 		 *        }
 		 *        }
 		 *      } );
 		 *      } );
-		 *      
+		 *
 		 *      oTable = $('#example').dataTable();
 		 *      oTable = $('#example').dataTable();
 		 *    } );
 		 *    } );
          */
          */
@@ -4710,7 +4710,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Immediately remove the first row
 		 *      // Immediately remove the first row
 		 *      oTable.fnDeleteRow( 0 );
 		 *      oTable.fnDeleteRow( 0 );
 		 *    } );
 		 *    } );
@@ -4896,7 +4896,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
 		 *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
 		 *      oTable.fnDraw();
 		 *      oTable.fnDraw();
 		 *    } );
 		 *    } );
@@ -4926,7 +4926,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Sometime later - filter...
 		 *      // Sometime later - filter...
 		 *      oTable.fnFilter( 'test string' );
 		 *      oTable.fnFilter( 'test string' );
 		 *    } );
 		 *    } );
@@ -5066,7 +5066,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Get the nodes from the table
 		 *      // Get the nodes from the table
 		 *      var nNodes = oTable.fnGetNodes( );
 		 *      var nNodes = oTable.fnGetNodes( );
 		 *    } );
 		 *    } );
@@ -5096,15 +5096,15 @@
 		 *      $('#example tbody td').click( function () {
 		 *      $('#example tbody td').click( function () {
 		 *        // Get the position of the current data from the node
 		 *        // Get the position of the current data from the node
 		 *        var aPos = oTable.fnGetPosition( this );
 		 *        var aPos = oTable.fnGetPosition( this );
-		 *        
+		 *
 		 *        // Get the data array for this row
 		 *        // Get the data array for this row
 		 *        var aData = oTable.fnGetData( aPos[0] );
 		 *        var aData = oTable.fnGetData( aPos[0] );
-		 *        
+		 *
 		 *        // Update the data array and return the value
 		 *        // Update the data array and return the value
 		 *        aData[ aPos[1] ] = 'clicked';
 		 *        aData[ aPos[1] ] = 'clicked';
 		 *        this.innerHTML = 'clicked';
 		 *        this.innerHTML = 'clicked';
 		 *      } );
 		 *      } );
-		 *      
+		 *
 		 *      // Init DataTables
 		 *      // Init DataTables
 		 *      oTable = $('#example').dataTable();
 		 *      oTable = $('#example').dataTable();
 		 *    } );
 		 *    } );
@@ -5134,7 +5134,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable;
 		 *      var oTable;
-		 *      
+		 *
 		 *      // 'open' an information row when a row is clicked on
 		 *      // 'open' an information row when a row is clicked on
 		 *      $('#example tbody tr').click( function () {
 		 *      $('#example tbody tr').click( function () {
 		 *        if ( oTable.fnIsOpen(this) ) {
 		 *        if ( oTable.fnIsOpen(this) ) {
@@ -5143,7 +5143,7 @@
 		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
 		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
 		 *        }
 		 *        }
 		 *      } );
 		 *      } );
-		 *      
+		 *
 		 *      oTable = $('#example').dataTable();
 		 *      oTable = $('#example').dataTable();
 		 *    } );
 		 *    } );
          */
          */
@@ -5176,7 +5176,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable;
 		 *      var oTable;
-		 *      
+		 *
 		 *      // 'open' an information row when a row is clicked on
 		 *      // 'open' an information row when a row is clicked on
 		 *      $('#example tbody tr').click( function () {
 		 *      $('#example tbody tr').click( function () {
 		 *        if ( oTable.fnIsOpen(this) ) {
 		 *        if ( oTable.fnIsOpen(this) ) {
@@ -5185,7 +5185,7 @@
 		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
 		 *          oTable.fnOpen( this, "Temporary row opened", "info_row" );
 		 *        }
 		 *        }
 		 *      } );
 		 *      } );
-		 *      
+		 *
 		 *      oTable = $('#example').dataTable();
 		 *      oTable = $('#example').dataTable();
 		 *    } );
 		 *    } );
          */
          */
@@ -5266,7 +5266,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Hide the second column after initialisation
 		 *      // Hide the second column after initialisation
 		 *      oTable.fnSetColumnVis( 1, false );
 		 *      oTable.fnSetColumnVis( 1, false );
 		 *    } );
 		 *    } );
@@ -5345,8 +5345,8 @@
             oSettings.aoOpenRows[i].nTr.colSpan = _fnVisbleColumns(oSettings);
             oSettings.aoOpenRows[i].nTr.colSpan = _fnVisbleColumns(oSettings);
           }
           }
 
 
-          /* Do a redraw incase anything depending on the table columns needs it 
-           * (built-in: scrolling) 
+          /* Do a redraw incase anything depending on the table columns needs it
+           * (built-in: scrolling)
            */
            */
           if (bRedraw === undefined || bRedraw) {
           if (bRedraw === undefined || bRedraw) {
             _fnAdjustColumnSizing(oSettings);
             _fnAdjustColumnSizing(oSettings);
@@ -5367,7 +5367,7 @@
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
 		 *      var oSettings = oTable.fnSettings();
 		 *      var oSettings = oTable.fnSettings();
-		 *      
+		 *
 		 *      // Show an example parameter from the settings
 		 *      // Show an example parameter from the settings
 		 *      alert( oSettings._iDisplayStart );
 		 *      alert( oSettings._iDisplayStart );
 		 *    } );
 		 *    } );
@@ -5386,7 +5386,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Sort immediately with columns 0 and 1
 		 *      // Sort immediately with columns 0 and 1
 		 *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
 		 *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
 		 *    } );
 		 *    } );
@@ -5408,7 +5408,7 @@
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
 		 *      var oTable = $('#example').dataTable();
 		 *      var oTable = $('#example').dataTable();
-		 *      
+		 *
 		 *      // Sort on column 1, when 'sorter' is clicked on
 		 *      // Sort on column 1, when 'sorter' is clicked on
 		 *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
 		 *      oTable.fnSortListener( document.getElementById('sorter'), 1 );
 		 *    } );
 		 *    } );
@@ -5434,10 +5434,10 @@
          *
          *
          *  @example
          *  @example
          *    $(document).ready(function() {
          *    $(document).ready(function() {
-		 *      var oTable = $('#example').dataTable();
-		 *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
-		 *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], 1, 0 ); // Row
-		 *    } );
+         *      var oTable = $('#example').dataTable();
+         *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
+         *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], 1, 0 ); // Row
+         *    } );
          */
          */
         this.fnUpdate = function (mData, mRow, iColumn, bRedraw, bAction) {
         this.fnUpdate = function (mData, mRow, iColumn, bRedraw, bAction) {
           var oSettings = _fnSettingsFromNode(this[DataTable.ext.iApiIndex]);
           var oSettings = _fnSettingsFromNode(this[DataTable.ext.iApiIndex]);
@@ -5795,8 +5795,8 @@
           }
           }
 
 
           if (oInit.bJQueryUI) {
           if (oInit.bJQueryUI) {
-            /* Use the JUI classes object for display. You could clone the oStdClasses object if 
-             * you want to have multiple tables with multiple independent classes 
+            /* Use the JUI classes object for display. You could clone the oStdClasses object if
+             * you want to have multiple tables with multiple independent classes
              */
              */
             $.extend(oSettings.oClasses, DataTable.ext.oJUIClasses);
             $.extend(oSettings.oClasses, DataTable.ext.oJUIClasses);
 
 
@@ -5842,7 +5842,7 @@
           /* Language definitions */
           /* Language definitions */
           if (oInit.oLanguage.sUrl !== "") {
           if (oInit.oLanguage.sUrl !== "") {
             /* Get the language definitions from a file - because this Ajax call makes the language
             /* Get the language definitions from a file - because this Ajax call makes the language
-             * get async to the remainder of this function we use bInitHandedOff to indicate that 
+             * get async to the remainder of this function we use bInitHandedOff to indicate that
              * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
              * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
              */
              */
             oSettings.oLanguage.sUrl = oInit.oLanguage.sUrl;
             oSettings.oLanguage.sUrl = oInit.oLanguage.sUrl;

+ 198 - 0
ambari-web/vendor/scripts/jquery.periodic.js

@@ -0,0 +1,198 @@
+/*!
+ * jQuery periodic plugin
+ *
+ * Copyright 2010, Tom Anderson
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ */
+
+jQuery.periodic = function (options, callback) {
+
+  // if the first argument is a function then assume the options aren't being passed
+  if (jQuery.isFunction(options)) {
+    callback = options;
+    options = {};
+  }
+
+  // Merge passed settings with default values
+  var settings = jQuery.extend({}, jQuery.periodic.defaults, {
+    ajax_complete : ajaxComplete,
+    increment     : increment,
+    reset         : reset,
+    cancel        : cancel
+  }, options);
+
+  // bookkeeping variables
+  settings.cur_period = settings.period;
+  settings.tid = false;
+  var prev_ajax_response = '';
+
+  run();
+
+  // return settings so user can tweak them externally
+  return settings;
+
+  // run (or restart if already running) the looping construct
+  function run() {
+    // clear/stop existing timer (multiple calls to run() won't result in multiple timers)
+    cancel();
+    // let it rip!
+    settings.tid = setTimeout(function() {
+      // set the context (this) for the callback to the settings object
+      callback.call(settings);
+
+      // compute the next value for cur_period
+      increment();
+
+      // queue up the next run
+      if(settings.tid)
+        run();
+    }, settings.cur_period);
+  }
+
+  // utility function for use with ajax calls
+  function ajaxComplete(xhr, status) {
+    if (status === 'success' && prev_ajax_response !== xhr.responseText) {
+      // reset the period whenever the response changes
+      prev_ajax_response = xhr.responseText;
+      reset();
+    }
+  }
+
+  // compute the next delay
+  function increment() {
+    settings.cur_period *= settings.decay;
+    if (settings.cur_period < settings.period) {
+      // don't let it drop below the minimum
+      reset();
+    } else if (settings.cur_period > settings.max_period) {
+      settings.cur_period = settings.max_period;
+      if (settings.on_max !== undefined) {
+        // call the user-supplied callback if we reach max_period
+        settings.on_max.call(settings);
+      }
+    }
+  }
+
+  function reset() {
+    settings.cur_period = settings.period;
+    // restart with the new timeout
+    run();
+  }
+
+  function cancel() {
+    clearTimeout(settings.tid);
+    settings.tid = null;
+  }
+
+  // other functions we might want to implement
+  function pause() {}
+  function resume() {}
+  function log() {}
+};
+
+jQuery.periodic.defaults = {
+    period       : 4000,      // 4 sec.
+    max_period   : 1800000,   // 30 min.
+    decay        : 1.5,       // time period multiplier
+    on_max       : undefined  // called if max_period is reached
+};
+/*!
+ * jQuery periodic plugin
+ *
+ * Copyright 2010, Tom Anderson
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ */
+
+jQuery.periodic = function (options, callback) {
+
+  // if the first argument is a function then assume the options aren't being passed
+  if (jQuery.isFunction(options)) {
+    callback = options;
+    options = {};
+  }
+
+  // Merge passed settings with default values
+  var settings = jQuery.extend({}, jQuery.periodic.defaults, {
+    ajax_complete : ajaxComplete,
+    increment     : increment,
+    reset         : reset,
+    cancel        : cancel
+  }, options);
+
+  // bookkeeping variables
+  settings.cur_period = settings.period;
+  settings.tid = false;
+  var prev_ajax_response = '';
+
+  run();
+
+  // return settings so user can tweak them externally
+  return settings;
+
+  // run (or restart if already running) the looping construct
+  function run() {
+    // clear/stop existing timer (multiple calls to run() won't result in multiple timers)
+    cancel();
+    // let it rip!
+    settings.tid = setTimeout(function() {
+      // set the context (this) for the callback to the settings object
+      callback.call(settings);
+
+      // compute the next value for cur_period
+      increment();
+      
+      // queue up the next run
+      if(settings.tid)
+        run();
+    }, settings.cur_period);
+  }
+
+  // utility function for use with ajax calls
+  function ajaxComplete(xhr, status) {
+    if (status === 'success' && prev_ajax_response !== xhr.responseText) {
+      // reset the period whenever the response changes
+      prev_ajax_response = xhr.responseText;
+      reset();
+    }
+  }
+
+  // compute the next delay
+  function increment() {
+    settings.cur_period *= settings.decay;
+    if (settings.cur_period < settings.period) {
+      // don't let it drop below the minimum
+      reset();
+    } else if (settings.cur_period > settings.max_period) {
+      settings.cur_period = settings.max_period;
+      if (settings.on_max !== undefined) {
+        // call the user-supplied callback if we reach max_period
+        settings.on_max.call(settings);
+      }
+    }
+  }
+
+  function reset() {
+    settings.cur_period = settings.period;
+    // restart with the new timeout
+    run();
+  }
+
+  function cancel() {
+    clearTimeout(settings.tid);
+    settings.tid = null;
+  }
+  
+  // other functions we might want to implement
+  function pause() {}
+  function resume() {}
+  function log() {}
+};
+
+jQuery.periodic.defaults = {
+    period       : 4000,      // 4 sec.
+    max_period   : 1800000,   // 30 min.
+    decay        : 1.5,       // time period multiplier
+    on_max       : undefined  // called if max_period is reached
+};

+ 180 - 0
ambari-web/vendor/styles/bootstrap-combobox.css

@@ -0,0 +1,180 @@
+.combobox-container {
+    margin-bottom: 5px;
+    *zoom: 1;
+}
+
+.combobox-container:before,
+.combobox-container:after {
+    display: table;
+    content: "";
+}
+
+.combobox-container:after {
+    clear: both;
+}
+
+.combobox-container input,
+.combobox-container .uneditable-input {
+    -webkit-border-radius: 0 3px 3px 0;
+    -moz-border-radius: 0 3px 3px 0;
+    border-radius: 0 3px 3px 0;
+}
+
+.combobox-container input:focus,
+.combobox-container .uneditable-input:focus {
+    position: relative;
+    z-index: 2;
+}
+
+.combobox-container .uneditable-input {
+    border-left-color: #ccc;
+}
+
+.combobox-container .add-on {
+    float: left;
+    display: block;
+    width: auto;
+    min-width: 16px;
+    height: 18px;
+    margin-right: -1px;
+    padding: 4px 5px;
+    font-weight: normal;
+    line-height: 18px;
+    color: #999999;
+    text-align: center;
+    text-shadow: 0 1px 0 #ffffff;
+    background-color: #f5f5f5;
+    border: 1px solid #ccc;
+    -webkit-border-radius: 3px 0 0 3px;
+    -moz-border-radius: 3px 0 0 3px;
+    border-radius: 3px 0 0 3px;
+}
+
+.combobox-container .active {
+    background-color: #a9dba9;
+    border-color: #46a546;
+}
+
+.combobox-container input,
+.combobox-container .uneditable-input {
+    float: left;
+    -webkit-border-radius: 3px 0 0 3px;
+    -moz-border-radius: 3px 0 0 3px;
+    border-radius: 3px 0 0 3px;
+}
+
+.combobox-container .uneditable-input {
+    border-left-color: #eee;
+    border-right-color: #ccc;
+}
+
+.combobox-container .add-on {
+    margin-right: 0;
+    margin-left: -1px;
+    -webkit-border-radius: 0 3px 3px 0;
+    -moz-border-radius: 0 3px 3px 0;
+    border-radius: 0 3px 3px 0;
+}
+
+.combobox-container input:first-child {
+    *margin-left: -160px;
+}
+
+.combobox-container input:first-child + .add-on {
+    *margin-left: -21px;
+}
+
+.combobox-container select {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    border: 0;
+    padding: 0;
+    margin: 0;
+    text-indent: -99999px;
+    *text-indent: 0;
+}
+
+.form-search .combobox-container,
+.form-inline .combobox-container {
+    display: inline-block;
+    margin-bottom: 0;
+    vertical-align: top;
+}
+
+.form-search .combobox-container .add-on,
+.form-inline .combobox-container .add-on {
+    vertical-align: middle;
+}
+
+.combobox-selected .combobox-clear {
+    display: inline-block;
+}
+
+.combobox-selected .caret {
+    display: none;
+}
+
+.combobox-clear {
+    display: none;
+    width: 14px;
+    height: 14px;
+    line-height: 14px;
+    vertical-align: top;
+    opacity: 0.3;
+    filter: alpha(opacity = 30);
+}
+
+.dropdown:hover .combobox-clear,
+.open.dropdown .combobox-clear {
+    opacity: 1;
+    filter: alpha(opacity = 100);
+}
+
+.btn .combobox-clear {
+    margin-top: 1px;
+    margin-left: 1px;
+}
+
+.btn:hover .combobox-clear,
+.open.btn-group .combobox-clear {
+    opacity: 1;
+    filter: alpha(opacity = 100);
+}
+
+.typeahead-long {
+    max-height: 300px;
+    overflow-y: auto;
+}
+
+.control-group.error .combobox-container .add-on {
+    color: #B94A48;
+    border-color: #B94A48;
+}
+
+.control-group.error .combobox-container .caret {
+    border-top-color: #B94A48;
+}
+
+.control-group.warning .combobox-container .add-on {
+    color: #C09853;
+    border-color: #C09853;
+}
+
+.control-group.warning .combobox-container .caret {
+    border-top-color: #C09853;
+}
+
+.control-group.success .combobox-container .add-on {
+    color: #468847;
+    border-color: #468847;
+}
+
+.control-group.success .combobox-container .caret {
+    border-top-color: #468847;
+}
+
+.combobox-container button.add-on {
+    height: 30px;
+    width: 30px;
+}

Some files were not shown because too many files changed in this diff