Browse Source

AMBARI-6779. Refactor Flume agents table to be more host centric (alexantonenko)

Alex Antonenko 10 years ago
parent
commit
6a91834c28

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

@@ -27,7 +27,7 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
    * @method startFlumeAgent
    * @method startFlumeAgent
    */
    */
   startFlumeAgent: function () {
   startFlumeAgent: function () {
-    var selectedFlumeAgent = this.get('selectedFlumeAgent');
+    var selectedFlumeAgent = arguments[0].context;
     if (selectedFlumeAgent && selectedFlumeAgent.get('status') === 'NOT_RUNNING') {
     if (selectedFlumeAgent && selectedFlumeAgent.get('status') === 'NOT_RUNNING') {
       var self = this;
       var self = this;
       App.showConfirmationPopup(function () {
       App.showConfirmationPopup(function () {
@@ -43,7 +43,7 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
    * @method stopFlumeAgent
    * @method stopFlumeAgent
    */
    */
   stopFlumeAgent: function () {
   stopFlumeAgent: function () {
-    var selectedFlumeAgent = this.get('selectedFlumeAgent');
+    var selectedFlumeAgent = arguments[0].context;
     if (selectedFlumeAgent && selectedFlumeAgent.get('status') === 'RUNNING') {
     if (selectedFlumeAgent && selectedFlumeAgent.get('status') === 'RUNNING') {
       var self = this;
       var self = this;
       App.showConfirmationPopup(function () {
       App.showConfirmationPopup(function () {
@@ -88,6 +88,12 @@ App.MainServiceInfoSummaryController = Em.Controller.extend({
     });
     });
   },
   },
 
 
+  gotoConfigs: function (){
+    App.router.get('mainServiceItemController').set('routeToConfigs', true);
+    App.router.transitionTo('main.services.service.configs', this.get('content'));
+    App.router.get('mainServiceItemController').set('routeToConfigs', false);
+  },
+
   nagiosUrl: function(){
   nagiosUrl: function(){
     return App.router.get('clusterController.nagiosUrl');
     return App.router.get('clusterController.nagiosUrl');
   }.property('App.router.clusterController.nagiosUrl'),
   }.property('App.router.clusterController.nagiosUrl'),

+ 3 - 6
ambari-web/app/messages.js

@@ -1912,16 +1912,13 @@ Em.I18n.translations = {
   'dashboard.services.mapreduce.jobTrackerUptime':'Job Trackers Uptime',
   'dashboard.services.mapreduce.jobTrackerUptime':'Job Trackers Uptime',
   'dashboard.services.mapreduce.chart.label':'Jobs Running',
   'dashboard.services.mapreduce.chart.label':'Jobs Running',
 
 
-  'dashboard.services.flume.summary.single':'1 Flume on ',
-  'dashboard.services.flume.summary.multiple':'{0} Flume on ',
-  'dashboard.services.flume.summary.hosts.single':'1 host',
-  'dashboard.services.flume.summary.hosts.multiple':'{0} hosts',
+  'dashboard.services.flume.summary.title':'Flume installed on {0} host{1} ({2} agent{3})',
+  'dashboard.services.flume.summary.configure':'Configure Agents',
   'dashboard.services.flume.agentsLabel': 'Flume',
   'dashboard.services.flume.agentsLabel': 'Flume',
   'dashboard.services.flume.channels': 'Channels',
   'dashboard.services.flume.channels': 'Channels',
   'dashboard.services.flume.sources': 'Sources',
   'dashboard.services.flume.sources': 'Sources',
   'dashboard.services.flume.sinks': 'Sinks',
   'dashboard.services.flume.sinks': 'Sinks',
-  'dashboard.services.flume.agent': '',
-
+  'dashboard.services.flume.agent': 'Agent',
 
 
   'dashboard.services.hbase.summary':'{0} region servers with {1} average load',
   'dashboard.services.hbase.summary':'{0} region servers with {1} average load',
   'dashboard.services.hbase.masterServer':'HBase Master',
   'dashboard.services.hbase.masterServer':'HBase Master',

+ 16 - 0
ambari-web/app/models/service/flume.js

@@ -54,7 +54,23 @@ App.FlumeAgent = DS.Model.extend({
       return App.healthIconClassYellow;
       return App.healthIconClassYellow;
       break;
       break;
     }
     }
+  }.property('status'),
+
+  displayStatus : function() {
+    switch (this.get('status')) {
+      case 'RUNNING':
+        return "Running";
+        break;
+      case 'NOT_RUNNING':
+        return "Stopped";
+        break;
+      case 'UNKNOWN':
+      default:
+        return "Unknown";
+        break;
+    }
   }.property('status')
   }.property('status')
+
 });
 });
 
 
 App.FlumeAgent.FIXTURES = [];
 App.FlumeAgent.FIXTURES = [];

File diff suppressed because it is too large
+ 2 - 3
ambari-web/app/styles/application.less


+ 86 - 50
ambari-web/app/templates/main/service/services/flume.hbs

@@ -19,62 +19,99 @@
 <!-- Flume Agents -->
 <!-- Flume Agents -->
     <div id="flume-summary">
     <div id="flume-summary">
       <a href="#" {{action filterHosts view.flumeHandlerComponent}}>{{view.summaryHeader}}</a>
       <a href="#" {{action filterHosts view.flumeHandlerComponent}}>{{view.summaryHeader}}</a>
-        <div class="btn-group display-inline-block flume-agents-actions pull-right">
-          <a {{bindAttr class=":btn :dropdown-toggle view.isActionsDisabled:disabled"}} data-toggle="dropdown" href="javascript:void(null)">{{t common.actions}}
-            <span class="caret"></span>
-          </a>
-          <ul class="pull-left dropdown-menu">
-            <li {{bindAttr class="view.isStartAgentDisabled:disabled"}}>
-              <a href="javascript:void(null)"
-                      {{bindAttr class="view.isStartAgentDisabled:disabled"}}
-                      {{action startFlumeAgent target="controller"}}>
-                {{t services.service.summary.flume.startAgent}}</a>
-            </li>
-            <li {{bindAttr class="view.isStopAgentDisabled:disabled"}}>
-              <a href="javascript:void(null)"
-                      {{bindAttr class="view.isStopAgentDisabled:disabled"}}
-                      {{action stopFlumeAgent target="controller"}}>
-                {{t services.service.summary.flume.stopAgent}}</a>
-            </li>
-          </ul>
-        </div>
-      <div class="scrollable-container">
+      <a href="#" class="pull-right" {{action gotoConfigs target="controller"}}>{{t dashboard.services.flume.summary.configure}}</a>
+      <div id="flume-agent-table" class="scrollable-container">
         <table class="table table-hover table-bordered table-striped" id="flume-agents-table">
         <table class="table table-hover table-bordered table-striped" id="flume-agents-table">
           <thead>
           <thead>
           {{#view view.sortView contentBinding="view.filteredContent" class="label-row"}}
           {{#view view.sortView contentBinding="view.filteredContent" class="label-row"}}
-            {{view view.parentView.statusSort}}
-            {{view view.parentView.agentSort}}
             {{view view.parentView.hostSort}}
             {{view view.parentView.hostSort}}
-            {{view view.parentView.sourceSort}}
-            {{view view.parentView.channelSort}}
-            {{view view.parentView.sinkSort}}
+            <th>{{t dashboard.services.flume.agent}}</th>
+            <th>{{t dashboard.services.flume.sources}}</th>
+            <th>{{t dashboard.services.flume.channels}}</th>
+            <th>{{t dashboard.services.flume.sinks}}</th>
           {{/view}}
           {{/view}}
           </thead>
           </thead>
-          <tbody>
           {{#if view.pageContent}}
           {{#if view.pageContent}}
-            {{#each agent in view.pageContent}}
-              {{#view view.agentView contentBinding="agent"}}
-                <td class="agent-status">
-                  <span {{bindAttr class="agent.healthClass"}}></span>
-                </td>
-                <td class="agent-name">
-                  {{agent.name}}
-                </td>
-                <td class="agent-host-name">
-                  <a href="javascript:void(null)" {{action showDetails agent.host}}>
-                    {{agent.hostName}}
-                  </a>
-                </td>
-                <td>
-                  {{agent.sourcesCount}}
-                </td>
-                <td>
-                  {{agent.channelsCount}}
-                </td>
-                <td>
-                  {{agent.sinksCount}}
-                </td>
-              {{/view}}
+            {{#each host in view.pageContent}}
+              <tbody>
+                {{#view view.agentView contentBinding="host"}}
+                  <td {{bindAttr rowspan="host.rowspan"}} id="flume-host-agent-row" class="agent-host-name">
+                      <a href="javascript:void(null)" {{action showDetails host.agents}}>
+                        {{host.hostName}}
+                      </a>
+                  </td>
+                  <td class="agent-status">
+                    <div class="wrapp-flume-status">
+                      <span {{bindAttr class="host.firtstAgent.healthClass"}}></span> {{host.firtstAgent.name}}
+                      <div class="btn-group display-inline-block flume-agents-actions">
+                          <a {{bindAttr class=":btn :dropdown-toggle"}} data-toggle="dropdown" href="javascript:void(null)">{{host.firtstAgent.displayStatus}}
+                              <span class="caret"></span>
+                          </a>
+                          <ul class="pull-left dropdown-menu">
+                              <li {{bindAttr class="host.firtstAgent.isStartAgentDisabled:disabled"}}>
+                                  <a href="javascript:void(null)"
+                                    {{bindAttr class="host.firtstAgent.isStartAgentDisabled:disabled"}}
+                                    {{action startFlumeAgent host.firtstAgent target="controller"}}>
+                                    {{t services.service.summary.flume.startAgent}}</a>
+                              </li>
+                              <li {{bindAttr class="host.firtstAgent.isStopAgentDisabled:disabled"}}>
+                                  <a href="javascript:void(null)"
+                                    {{bindAttr class="host.firtstAgent.isStopAgentDisabled:disabled"}}
+                                    {{action stopFlumeAgent host.firtstAgent target="controller"}}>
+                                    {{t services.service.summary.flume.stopAgent}}</a>
+                              </li>
+                          </ul>
+                      </div>
+                    </div>
+                  </td>
+                  <td>
+                    {{host.firtstAgent.sourcesCount}}
+                  </td>
+                  <td>
+                    {{host.firtstAgent.channelsCount}}
+                  </td>
+                  <td>
+                    {{host.firtstAgent.sinksCount}}
+                  </td>
+                {{/view}}
+                {{#each agent in host.otherAgents}}
+                  <tr>
+                    <td class="agent-status">
+                        <div class="wrapp-flume-status">
+                            <span {{bindAttr class="agent.healthClass"}}></span> {{agent.name}}
+                            <div class="btn-group display-inline-block flume-agents-actions">
+                                <a {{bindAttr class=":btn :dropdown-toggle"}} data-toggle="dropdown" href="javascript:void(null)">{{agent.displayStatus}}
+                                    <span class="caret"></span>
+                                </a>
+                                <ul class="pull-left dropdown-menu">
+                                    <li {{bindAttr class="agent.isStartAgentDisabled:disabled"}}>
+                                        <a href="javascript:void(null)"
+                                          {{bindAttr class="agent.isStartAgentDisabled:disabled"}}
+                                          {{action startFlumeAgent agent target="controller"}}>
+                                          {{t services.service.summary.flume.startAgent}}</a>
+                                    </li>
+                                    <li {{bindAttr class="agent.isStopAgentDisabled:disabled"}}>
+                                        <a href="javascript:void(null)"
+                                          {{bindAttr class="agent.isStopAgentDisabled:disabled"}}
+                                          {{action stopFlumeAgent agent target="controller"}}>
+                                          {{t services.service.summary.flume.stopAgent}}</a>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </td>
+                    <td>
+                      {{agent.sourcesCount}}
+                    </td>
+                    <td>
+                      {{agent.channelsCount}}
+                    </td>
+                    <td>
+                      {{agent.sinksCount}}
+                    </td>
+                  </tr>
+                {{/each}}
+              </tbody>
             {{/each}}
             {{/each}}
           {{else}}
           {{else}}
             <tr>
             <tr>
@@ -83,7 +120,6 @@
               </td>
               </td>
             </tr>
             </tr>
           {{/if}}
           {{/if}}
-          </tbody>
         </table>
         </table>
       </div>
       </div>
     </div>
     </div>

+ 45 - 69
ambari-web/app/views/main/service/services/flume.js

@@ -24,25 +24,32 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
 
 
   pagination: false,
   pagination: false,
 
 
-  isActionsDisabled: true,
-
-  isStartAgentDisabled: true,
-
-  isStopAgentDisabled: true,
+  selectedHost: null,
 
 
   content: function () {
   content: function () {
-    return this.get('service.agents');
-  }.property('service.agents.length'),
+    var hostNames = this.get('service.agents').mapProperty('hostName').uniq(),
+    content = [],
+    self = this;
+    hostNames.forEach(function(hostName) {
+      var agents = self.get('service.agents').filterProperty('hostName', hostName);
+      content.push(
+        Em.Object.create({
+          hostName: hostName,
+          agents: agents,
+          rowspan: agents.length,
+          firtstAgent: agents[0],
+          otherAgents: agents.without(agents[0])
+        })
+      );
+    });
+    return content;
+  }.property('service.agents.length', 'service.@each.agents'),
 
 
   summaryHeader: function () {
   summaryHeader: function () {
-    var agents = App.FlumeService.find().objectAt(0).get('agents');//this.get('service.agents');
-    var agentCount = agents.get('length');
-    var hostCount = this.get('service.flumeHandlersTotal');
-    var prefix = agentCount == 1 ? this.t("dashboard.services.flume.summary.single") :
-        this.t("dashboard.services.flume.summary.multiple").format(agentCount);
-    var suffix = hostCount == 1 ? this.t("dashboard.services.flume.summary.hosts.single") :
-        this.t("dashboard.services.flume.summary.hosts.multiple").format(hostCount);
-    return prefix + suffix;
+    var agents = App.FlumeService.find().objectAt(0).get('agents'),
+    agentCount = agents.get('length'),
+    hostCount = this.get('service.flumeHandlersTotal');
+    return this.t("dashboard.services.flume.summary.title").format(hostCount, (hostCount > 1 ? "s" : ""), agentCount,  (agentCount > 1 ? "s" : ""));
   }.property('service.agents', 'service.hostComponents.length'),
   }.property('service.agents', 'service.hostComponents.length'),
 
 
   flumeHandlerComponent: function () {
   flumeHandlerComponent: function () {
@@ -55,57 +62,26 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
   agentView: Em.View.extend({
   agentView: Em.View.extend({
     content: null,
     content: null,
     tagName: 'tr',
     tagName: 'tr',
-    classNameBindings: ['selectedClass', ':agent-row'],
 
 
-    selectedClass: function () {
-      return this.get('controller.selectedFlumeAgent.id') === this.get('content.id') ? 'highlight' : '';
-    }.property('controller.selectedFlumeAgent'),
-
-    click: function () {
-      this.get('parentView').showAgentInfo(this.get('content'));
+    click: function (e) {
+      var numberOfAgents = this.get('content.agents').length;
+      if($(e.target).attr('id') == "flume-host-agent-row"){
+        $(e.currentTarget).parents("table:first").find('tr').removeClass('highlight');
+        $(e.currentTarget).addClass('highlight').nextAll("tr").slice(0,numberOfAgents - 1).addClass('highlight');
+        this.get('parentView').showAgentInfo(this.get('content'));
+      }
     }
     }
   }),
   }),
 
 
   sortView: sort.wrapperView,
   sortView: sort.wrapperView,
 
 
-  statusSort: sort.fieldView.extend({
-    column: '1',
-    name: 'status',
-    displayName: ''
-  }),
-
-  agentSort: sort.fieldView.extend({
-    column: '2',
-    name: 'name',
-    displayName: Em.I18n.t('dashboard.services.flume.agent')
-  }),
-
   hostSort: sort.fieldView.extend({
   hostSort: sort.fieldView.extend({
-    column: '3',
+    column: '1',
     name: 'hostName',
     name: 'hostName',
     displayName: Em.I18n.t('common.host')
     displayName: Em.I18n.t('common.host')
   }),
   }),
 
 
-  sourceSort: sort.fieldView.extend({
-    column: '4',
-    name: 'sourcesCount',
-    displayName: Em.I18n.t('dashboard.services.flume.sources')
-  }),
-
-  channelSort: sort.fieldView.extend({
-    column: '5',
-    name: 'channelsCount',
-    displayName: Em.I18n.t('dashboard.services.flume.channels')
-  }),
-
-  sinkSort: sort.fieldView.extend({
-    column: '6',
-    name: 'sinksCount',
-    displayName: Em.I18n.t('dashboard.services.flume.sinks')
-  }),
-
   didInsertElement: function () {
   didInsertElement: function () {
-    this.set('controller.selectedFlumeAgent', null);
     this.filter();
     this.filter();
   },
   },
 
 
@@ -113,13 +89,13 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
    * Change classes for dropdown DOM elements after status change of selected agent
    * Change classes for dropdown DOM elements after status change of selected agent
    */
    */
   setActionsDropdownClasses: function () {
   setActionsDropdownClasses: function () {
-    var selectedFlumeAgent = this.get('controller.selectedFlumeAgent');
-    this.set('isActionsDisabled', !selectedFlumeAgent);
-    if (selectedFlumeAgent) {
-      this.set('isStartAgentDisabled', selectedFlumeAgent.get('status') !== 'NOT_RUNNING');
-      this.set('isStopAgentDisabled', selectedFlumeAgent.get('status') !== 'RUNNING');
-    }
-  }.observes('controller.selectedFlumeAgent', 'controller.selectedFlumeAgent.status'),
+    this.get('content').forEach(function(hosts){
+      hosts.agents.forEach(function (agent) {
+        agent.set('isStartAgentDisabled', agent.get('status') !== 'NOT_RUNNING');
+        agent.set('isStopAgentDisabled', agent.get('status') !== 'RUNNING');
+      });
+    });
+  }.observes('content.@each.agents.@each.status'),
 
 
   /**
   /**
    * Action handler from flume tepmlate.
    * Action handler from flume tepmlate.
@@ -128,9 +104,9 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
    * @method showAgentInfo
    * @method showAgentInfo
    * @param {object} agent
    * @param {object} agent
    */
    */
-  showAgentInfo: function (agent) {
-    this.set('controller.selectedFlumeAgent', agent);
-    this.setAgentMetrics(agent);
+  showAgentInfo: function (host) {
+    this.set('selectedHost', host);
+    this.setAgentMetrics(host);
   },
   },
   /**
   /**
    * Show Flume agent metric.
    * Show Flume agent metric.
@@ -138,19 +114,19 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
    * @method setFlumeAgentMetric
    * @method setFlumeAgentMetric
    * @param {object} agent - DS.model of agent
    * @param {object} agent - DS.model of agent
    */
    */
-  setAgentMetrics: function(agent) {
+  setAgentMetrics: function(host) {
     var getMetricTitle = function(metricTypeKey, hostName) {
     var getMetricTitle = function(metricTypeKey, hostName) {
       var metricType = Em.I18n.t('services.service.info.metrics.flume.' + metricTypeKey).format(Em.I18n.t('common.metrics'));
       var metricType = Em.I18n.t('services.service.info.metrics.flume.' + metricTypeKey).format(Em.I18n.t('common.metrics'));
       return  metricType + ' - ' + hostName;
       return  metricType + ' - ' + hostName;
     };
     };
     var gangliaUrlTpl = App.router.get('clusterController.gangliaUrl') + '/?r=hour&cs=&ce=&m=load_one&s=by+name&c=HDPFlumeServer&h={0}&host_regex=&max_graphs=0&tab=m&vn=&sh=1&z=small&hc=4';
     var gangliaUrlTpl = App.router.get('clusterController.gangliaUrl') + '/?r=hour&cs=&ce=&m=load_one&s=by+name&c=HDPFlumeServer&h={0}&host_regex=&max_graphs=0&tab=m&vn=&sh=1&z=small&hc=4';
-    var agentHostMock = agent.get('hostName');
+    var agentHostMock = host.get('hostName');
     var mockMetricData = [
     var mockMetricData = [
       {
       {
         header: 'channelName',
         header: 'channelName',
         metricView: App.MainServiceInfoFlumeGraphsView.extend(),
         metricView: App.MainServiceInfoFlumeGraphsView.extend(),
         metricViewData: {
         metricViewData: {
-          agent: agent,
+          agent: host,
           metricType: 'CHANNEL'
           metricType: 'CHANNEL'
         }
         }
       },
       },
@@ -158,7 +134,7 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
         header: 'sinkName',
         header: 'sinkName',
         metricView: App.MainServiceInfoFlumeGraphsView.extend(),
         metricView: App.MainServiceInfoFlumeGraphsView.extend(),
         metricViewData: {
         metricViewData: {
-          agent: agent,
+          agent: host,
           metricType: 'SINK'
           metricType: 'SINK'
         }
         }
       },
       },
@@ -166,7 +142,7 @@ App.MainDashboardServiceFlumeView = App.TableView.extend({
         header: 'sourceName',
         header: 'sourceName',
         metricView: App.MainServiceInfoFlumeGraphsView.extend(),
         metricView: App.MainServiceInfoFlumeGraphsView.extend(),
         metricViewData: {
         metricViewData: {
-          agent: agent,
+          agent: host,
           metricType: 'SOURCE'
           metricType: 'SOURCE'
         }
         }
       }
       }

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