Browse Source

AMBARI-15604 Alert Definitions Repeat Tolerance Values Exposed In Web Client (zhewang)

Zhe (Joe) Wang 9 years ago
parent
commit
2486b8cbb7

+ 2 - 2
ambari-web/app/controllers/global/update_controller.js

@@ -544,8 +544,8 @@ App.UpdateController = Em.Controller.extend({
   updateAlertDefinitions: function (callback) {
   updateAlertDefinitions: function (callback) {
     var testUrl = '/data/alerts/alertDefinitions.json';
     var testUrl = '/data/alerts/alertDefinitions.json';
     var realUrl = '/alert_definitions?fields=' +
     var realUrl = '/alert_definitions?fields=' +
-      'AlertDefinition/component_name,AlertDefinition/description,AlertDefinition/enabled,AlertDefinition/id,' +
-      'AlertDefinition/ignore_host,AlertDefinition/interval,AlertDefinition/label,AlertDefinition/name,' +
+      'AlertDefinition/component_name,AlertDefinition/description,AlertDefinition/enabled,AlertDefinition/repeat_tolerance,AlertDefinition/repeat_tolerance_enabled,' +
+      'AlertDefinition/id,AlertDefinition/ignore_host,AlertDefinition/interval,AlertDefinition/label,AlertDefinition/name,' +
       'AlertDefinition/scope,AlertDefinition/service_name,AlertDefinition/source';
       'AlertDefinition/scope,AlertDefinition/service_name,AlertDefinition/source';
     var url = this.getUrl(testUrl, realUrl);
     var url = this.getUrl(testUrl, realUrl);
 
 

+ 93 - 7
ambari-web/app/controllers/main/alerts/definition_details_controller.js

@@ -16,6 +16,8 @@
  * limitations under the License.
  * limitations under the License.
  */
  */
 
 
+var validator = require('utils/validator');
+
 App.MainAlertDefinitionDetailsController = Em.Controller.extend({
 App.MainAlertDefinitionDetailsController = Em.Controller.extend({
 
 
   name: 'mainAlertDefinitionDetailsController',
   name: 'mainAlertDefinitionDetailsController',
@@ -228,31 +230,115 @@ App.MainAlertDefinitionDetailsController = Em.Controller.extend({
     });
     });
 
 
     return App.showConfirmationFeedBackPopup(function (query) {
     return App.showConfirmationFeedBackPopup(function (query) {
-      self.toggleDefinitionState(alertDefinition);
+      self.toggleDefinitionState(alertDefinition, "enabled");
     }, bodyMessage);
     }, bodyMessage);
   },
   },
 
 
   /**
   /**
    * Enable/disable alertDefinition
    * Enable/disable alertDefinition
    * @param {object} alertDefinition
    * @param {object} alertDefinition
+   * @param {string} property
    * @returns {$.ajax}
    * @returns {$.ajax}
    * @method toggleDefinitionState
    * @method toggleDefinitionState
    */
    */
-  toggleDefinitionState: function (alertDefinition) {
-    var newState = !alertDefinition.get('enabled');
-    alertDefinition.set('enabled', newState);
+  toggleDefinitionState: function (alertDefinition, property) {
+    var newState = !alertDefinition.get(property);
+    alertDefinition.set(property, newState);
+    var data = {};
+    data['AlertDefinition/' + property] = newState;
     return App.ajax.send({
     return App.ajax.send({
       name: 'alerts.update_alert_definition',
       name: 'alerts.update_alert_definition',
       sender: this,
       sender: this,
       data: {
       data: {
         id: alertDefinition.get('id'),
         id: alertDefinition.get('id'),
-        data: {
-          "AlertDefinition/enabled": newState
-        }
+        data: data
       }
       }
     });
     });
   },
   },
 
 
+  /**
+   * "Disable / Enable Repeat Tolerance" button handler
+   * @method toggleRepeatTolerance
+   */
+  toggleRepeatTolerance: function () {
+    var alertDefinition = this.get('content');
+    var self = this;
+    var bodyMessage = Em.Object.create({
+      confirmMsg: alertDefinition.get('repeat_tolerance_enabled') ? Em.I18n.t('alerts.table.repeatTolerance.enabled.confirm.msg') : Em.I18n.t('alerts.table.repeatTolerance.disabled.confirm.msg').format(alertDefinition.get('repeat_tolerance') || 1),
+      confirmButton: Em.I18n.t('common.confirm')
+    });
+
+    return App.showConfirmationFeedBackPopup(function (query) {
+      self.toggleDefinitionState(alertDefinition, "repeat_tolerance_enabled");
+    }, bodyMessage);
+  },
+
+  editRepeatTolerance: function () {
+    var self = this;
+    var alertDefinition = this.get('content');
+
+    var loadingPopup = App.ModalPopup.show({
+      header: Em.I18n.t('jobs.loadingTasks'),
+      primary: false,
+      secondary: false,
+      bodyClass: Em.View.extend({
+        template: Em.Handlebars.compile('{{view App.SpinnerView}}')
+      })
+    });
+
+    App.router.get('mainAlertDefinitionActionsController').loadClusterConfig().done(function (data) {
+      var tag = [
+        {
+          siteName: 'cluster-env',
+          tagName: data.Clusters.desired_configs['cluster-env'].tag,
+          newTagName: null
+        }
+      ];
+      App.router.get('configurationController').getConfigsByTags(tag).done(function (config) {
+        var configProperties = config[0].properties;
+
+        loadingPopup.hide();
+        return App.ModalPopup.show({
+          classNames: ['fourty-percent-width-modal'],
+          header: Em.I18n.t('alerts.actions.editRepeatTolerance.header'),
+          primary: Em.I18n.t('common.save'),
+          secondary: Em.I18n.t('common.cancel'),
+          inputValue: self.get('content.repeat_tolerance') || 1,
+          errorMessage: Em.I18n.t('alerts.actions.editRepeatTolerance.error'),
+          isInvalid: function () {
+            var intValue = Number(this.get('inputValue'));
+            return this.get('inputValue') !== 'DEBUG' && (!validator.isValidInt(intValue) || intValue < 1);
+          }.property('inputValue'),
+          disablePrimary: Em.computed.alias('isInvalid'),
+          onPrimary: function () {
+            if (this.get('isInvalid')) {
+              return;
+            }
+            self.set('content.repeat_tolerance', this.get('inputValue'));
+            App.ajax.send({
+              name: 'alerts.update_alert_definition',
+              sender: self,
+              data: {
+                id: alertDefinition.get('id'),
+                data: {
+                  "AlertDefinition/repeat_tolerance": this.get('inputValue')
+                }
+              }
+            });
+            this.hide();
+          },
+          bodyClass: Ember.View.extend({
+            templateName: require('templates/common/modal_popups/prompt_popup'),
+            text: Em.I18n.t('alerts.actions.editRepeatTolerance.body').format(configProperties.alerts_repeat_tolerance || "1"),
+            title: Em.I18n.t('alerts.actions.editRepeatTolerance.title'),
+            description: Em.I18n.t('alerts.actions.editRepeatTolerance.description'),
+            label: Em.I18n.t('alerts.actions.editRepeatTolerance.label')
+          })
+        });
+      });
+    });
+  },
+
   /**
   /**
    * Define if label or configs are in edit mode
    * Define if label or configs are in edit mode
    * @type {Boolean}
    * @type {Boolean}

+ 2 - 0
ambari-web/app/mappers/alert_definitions_mapper.js

@@ -34,6 +34,8 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({
     service_name: 'AlertDefinition.service_name',
     service_name: 'AlertDefinition.service_name',
     component_name: 'AlertDefinition.component_name',
     component_name: 'AlertDefinition.component_name',
     enabled: 'AlertDefinition.enabled',
     enabled: 'AlertDefinition.enabled',
+    repeat_tolerance_enabled: 'AlertDefinition.repeat_tolerance_enabled',
+    repeat_tolerance: 'AlertDefinition.repeat_tolerance',
     scope: 'AlertDefinition.scope',
     scope: 'AlertDefinition.scope',
     interval: 'AlertDefinition.interval',
     interval: 'AlertDefinition.interval',
     helpUrl: 'AlertDefinition.help_url',
     helpUrl: 'AlertDefinition.help_url',

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

@@ -1002,6 +1002,8 @@ Em.I18n.translations = {
   'alerts.actions.manageNotifications': 'Manage Notifications',
   'alerts.actions.manageNotifications': 'Manage Notifications',
   'alerts.actions.manageNotifications.info': 'You can manage notification methods and recipients.',
   'alerts.actions.manageNotifications.info': 'You can manage notification methods and recipients.',
   'alerts.actions.editRepeatTolerance.text': 'Manage global setting for alerts',
   'alerts.actions.editRepeatTolerance.text': 'Manage global setting for alerts',
+  'alerts.actions.editRepeatTolerance.header': 'Edit Alert Check Retry Count',
+  'alerts.actions.editRepeatTolerance.body': 'This will override the global check retry count {0} for this alert.',
   'alerts.actions.editRepeatTolerance.title': 'Alert Check Retries',
   'alerts.actions.editRepeatTolerance.title': 'Alert Check Retries',
   'alerts.actions.editRepeatTolerance.description': 'Set the amount of alert check retries to perform before dispatching a notification.' +
   'alerts.actions.editRepeatTolerance.description': 'Set the amount of alert check retries to perform before dispatching a notification.' +
     'If during an alert check a state change occurs, Ambari will retry this number of times before dispatching a notification. Increase this number if your environment experiences temporal issues.',
     'If during an alert check a state change occurs, Ambari will retry this number of times before dispatching a notification. Increase this number if your environment experiences temporal issues.',
@@ -1023,6 +1025,8 @@ Em.I18n.translations = {
   'alerts.table.header.check.response': 'Response',
   'alerts.table.header.check.response': 'Response',
   'alerts.table.header.definitionName': 'Alert Definition Name',
   'alerts.table.header.definitionName': 'Alert Definition Name',
   'alerts.table.header.notification': 'Notification',
   'alerts.table.header.notification': 'Notification',
+  'alerts.table.header.repeatTolerance': 'Alert Check Retry Count',
+  'alerts.table.header.repeatToleranceEnabled': 'Alert Check Retries',
   'alerts.table.state': 'State',
   'alerts.table.state': 'State',
   'alerts.table.state.enabled': 'Enabled',
   'alerts.table.state.enabled': 'Enabled',
   'alerts.table.state.disabled': 'Disabled',
   'alerts.table.state.disabled': 'Disabled',
@@ -1032,6 +1036,10 @@ Em.I18n.translations = {
   'alerts.table.state.disabled.confirm.msg': 'You are about to Enable this alert definition.',
   'alerts.table.state.disabled.confirm.msg': 'You are about to Enable this alert definition.',
   'alerts.table.state.enabled.confirm.btn': 'Confirm Disable',
   'alerts.table.state.enabled.confirm.btn': 'Confirm Disable',
   'alerts.table.state.disabled.confirm.btn': 'Confirm Enable',
   'alerts.table.state.disabled.confirm.btn': 'Confirm Enable',
+  'alerts.table.repeatTolerance.enabled.tooltip': 'Click to disable alert check retries',
+  'alerts.table.repeatTolerance.disabled.tooltip': 'Click to enable alert check retries',
+  'alerts.table.repeatTolerance.enabled.confirm.msg': 'You are about to disable alert check retries. By disabling retries, on each state change, an alert notification will be dispatched.',
+  'alerts.table.repeatTolerance.disabled.confirm.msg': 'You are about to enable alert check retries. By enabling retries, on each state change, Ambari will retry the check {0} times before dispatching an alert notification.',
   'alerts.filters.filteredAlertsInfo': '{0} of {1} definitions showing',
   'alerts.filters.filteredAlertsInfo': '{0} of {1} definitions showing',
   'alerts.definition.name': 'Alert Definition Name',
   'alerts.definition.name': 'Alert Definition Name',
   'alerts.saveChanges': 'You have unsaved changes',
   'alerts.saveChanges': 'You have unsaved changes',

+ 2 - 0
ambari-web/app/models/alerts/alert_definition.js

@@ -35,6 +35,8 @@ App.AlertDefinition = DS.Model.extend({
   serviceName: DS.attr('string'),
   serviceName: DS.attr('string'),
   componentName: DS.attr('string'),
   componentName: DS.attr('string'),
   enabled: DS.attr('boolean'),
   enabled: DS.attr('boolean'),
+  repeat_tolerance_enabled: DS.attr('boolean'),
+  repeat_tolerance: DS.attr('number'),
   scope: DS.attr('string'),
   scope: DS.attr('string'),
   interval: DS.attr('number'),
   interval: DS.attr('number'),
   type: DS.attr('string'),
   type: DS.attr('string'),

+ 6 - 3
ambari-web/app/styles/alerts.less

@@ -656,7 +656,10 @@
   }
   }
 }
 }
 /*****end styles for alert popup*****/
 /*****end styles for alert popup*****/
-.enable-disable-button::before {
-  font-family: FontAwesome;
-  content: "\f011";
+.enable-disable-button,
+.repeat-tolerance-button {
+  &::before {
+    font-family: FontAwesome;
+    content: "\f011";
+  }
 }
 }

+ 55 - 14
ambari-web/app/templates/main/alerts/definition_details.hbs

@@ -63,7 +63,7 @@
 
 
     {{! Left column }}
     {{! Left column }}
     {{! Alert Definition Configs }}
     {{! Alert Definition Configs }}
-    <div class="box span9">
+    <div class="box span8">
       <div class="box-header">
       <div class="box-header">
         <div class="pull-left">
         <div class="pull-left">
           <h4>{{t common.configuration}}</h4>
           <h4>{{t common.configuration}}</h4>
@@ -94,11 +94,11 @@
     {{! Left column end }}
     {{! Left column end }}
 
 
     {{! Right column }}
     {{! Right column }}
-    <div class="span3 right-column">
+    <div class="span4 right-column">
       <div class="properties-list background-text">
       <div class="properties-list background-text">
         <div class="row-fluid">
         <div class="row-fluid">
-          <div class="span5 property-name">{{t alerts.table.state}}:</div>
-          <div class="span7">
+          <div class="span6 property-name">{{t alerts.table.state}}:</div>
+          <div class="span6">
             {{#if controller.content.enabled}}
             {{#if controller.content.enabled}}
               {{#isAuthorized "SERVICE.TOGGLE_ALERTS"}}
               {{#isAuthorized "SERVICE.TOGGLE_ALERTS"}}
                 <a href="#" {{action "toggleState" controller.content target="controller"}} {{bindAttr class="controller.content.enabled:alert-definition-enable:alert-definition-disable"}}>
                 <a href="#" {{action "toggleState" controller.content target="controller"}} {{bindAttr class="controller.content.enabled:alert-definition-enable:alert-definition-disable"}}>
@@ -126,26 +126,26 @@
         </div>
         </div>
         {{#if controller.content.serviceDisplayName}}
         {{#if controller.content.serviceDisplayName}}
           <div class="row-fluid">
           <div class="row-fluid">
-            <div class="span5 property-name">{{t common.service}}:</div>
-            <div class="span7"><span>{{controller.content.serviceDisplayName}}</span></div>
+            <div class="span6 property-name">{{t common.service}}:</div>
+            <div class="span6"><span>{{controller.content.serviceDisplayName}}</span></div>
           </div>
           </div>
         {{/if}}
         {{/if}}
         {{#if controller.content.componentNameFormatted}}
         {{#if controller.content.componentNameFormatted}}
           <div class="row-fluid">
           <div class="row-fluid">
-            <div class="span5 property-name">{{t common.component}}:</div>
-            <div class="span7">{{controller.content.componentNameFormatted}}</div>
+            <div class="span6 property-name">{{t common.component}}:</div>
+            <div class="span6">{{controller.content.componentNameFormatted}}</div>
           </div>
           </div>
         {{/if}}
         {{/if}}
         <div class="row-fluid">
         <div class="row-fluid">
-          <div class="span5 property-name">{{t common.type}}:</div>
-          <div class="span7">
+          <div class="span6 property-name">{{t common.type}}:</div>
+          <div class="span6">
             <span {{bindAttr class=":type-icon  controller.content.typeIconClass"}}></span> {{controller.content.type}}
             <span {{bindAttr class=":type-icon  controller.content.typeIconClass"}}></span> {{controller.content.type}}
           </div>
           </div>
         </div>
         </div>
         {{#if controller.groupsList.length}}
         {{#if controller.groupsList.length}}
           <div class="row-fluid">
           <div class="row-fluid">
-            <div class="span5 property-name">{{t alerts.definition.details.groups}}:</div>
-            <div class="span7">
+            <div class="span6 property-name">{{t alerts.definition.details.groups}}:</div>
+            <div class="span6">
               <ul>
               <ul>
                 {{#each groupName in controller.groupsList}}
                 {{#each groupName in controller.groupsList}}
                   <li>{{groupName}}</li>
                   <li>{{groupName}}</li>
@@ -155,9 +155,50 @@
           </div>
           </div>
         {{/if}}
         {{/if}}
         <div class="row-fluid">
         <div class="row-fluid">
-          <div class="span5 property-name">{{t alerts.table.header.lastTrigger}}:</div>
-          <div class="span7">{{controller.content.lastTriggeredFormatted}}</div>
+          <div class="span6 property-name">{{t alerts.table.header.lastTrigger}}:</div>
+          <div class="span6">{{controller.content.lastTriggeredFormatted}}</div>
         </div>
         </div>
+        <div class="row-fluid">
+          <div class="span6 property-name">{{t alerts.table.header.repeatToleranceEnabled}}:</div>
+          <div class="span6">
+            {{#if controller.content.repeat_tolerance_enabled}}
+              {{#isAuthorized "SERVICE.TOGGLE_ALERTS"}}
+                <a href="#" {{action toggleRepeatTolerance target="controller"}} {{bindAttr class="controller.content.repeat_tolerance_enabled:alert-definition-enable:alert-definition-disable"}}>
+                  <span class="repeat-tolerance-button" {{translateAttr data-original-title="alerts.table.repeatTolerance.enabled.tooltip"}}>
+                    {{view.enabledDisplay}}
+                  </span>
+                </a>
+              {{else}}
+                {{view.enabledDisplay}}
+              {{/isAuthorized}}
+            {{else}}
+              {{#isAuthorized "SERVICE.TOGGLE_ALERTS"}}
+                <a href="#" {{action toggleRepeatTolerance target="controller"}} {{bindAttr class="controller.content.repeat_tolerance_enabled:alert-definition-enable:alert-definition-disable"}}>
+                  <span class="repeat-tolerance-button" {{translateAttr data-original-title="alerts.table.repeatTolerance.disabled.tooltip"}}>
+                    {{view.disabledDisplay}}
+                  </span>
+                </a>
+              {{else}}
+                {{view.disabledDisplay}}
+              {{/isAuthorized}}
+            {{/if}}
+          </div>
+        </div>
+        {{#if controller.content.repeat_tolerance_enabled}}
+          <div class="row-fluid">
+            <div class="span6 property-name">{{t alerts.table.header.repeatTolerance}}:</div>
+            <div class="span6">
+              <span>
+                {{controller.content.repeat_tolerance}}
+              </span>
+              {{#isAuthorized "SERVICE.TOGGLE_ALERTS"}}
+                <a {{action editRepeatTolerance target="controller"}} class="edit-description-button">
+                  <i class="icon-pencil"></i>
+                </a>
+              {{/isAuthorized}}
+            </div>
+          </div>
+        {{/if}}
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>

+ 1 - 1
ambari-web/app/views/main/alerts/definition_configs_view.js

@@ -40,7 +40,7 @@ App.AlertDefinitionConfigsView = Em.View.extend({
    * List of classes applied to all inputs
    * List of classes applied to all inputs
    * @type {String}
    * @type {String}
    */
    */
-  basicClass: 'span9',
+  basicClass: 'span11',
 
 
   init: function () {
   init: function () {
     this.set('controller.canEdit', this.get('canEdit'));
     this.set('controller.canEdit', this.get('canEdit'));

+ 1 - 0
ambari-web/app/views/main/alerts/definition_details_view.js

@@ -93,6 +93,7 @@ App.MainAlertDefinitionDetailsView = App.TableView.extend({
   tooltipsUpdater: function () {
   tooltipsUpdater: function () {
     Em.run.next(function () {
     Em.run.next(function () {
       App.tooltip($(".enable-disable-button"));
       App.tooltip($(".enable-disable-button"));
+      App.tooltip($(".repeat-tolerance-button"));
     });
     });
   }.observes('controller.content.enabled'),
   }.observes('controller.content.enabled'),
 
 

+ 1 - 1
ambari-web/test/views/main/alerts/definition_details_view_test.js

@@ -155,7 +155,7 @@ describe('App.MainAlertDefinitionDetailsView', function () {
     it("Em.run.next should be called", function () {
     it("Em.run.next should be called", function () {
       view.tooltipsUpdater();
       view.tooltipsUpdater();
       expect(Em.run.next.calledOnce).to.be.true;
       expect(Em.run.next.calledOnce).to.be.true;
-      expect(App.tooltip.calledOnce).to.be.true;
+      expect(App.tooltip.calledTwice).to.be.true;
     });
     });
   });
   });