You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ha...@apache.org on 2021/01/26 11:57:46 UTC

[ambari] branch branch-2.7 updated: AMBARI-25612. Ambari stops alert notices dispatching on unhandled exception inside. (dvitiuk via dgrinenko) (#3280)

This is an automated email from the ASF dual-hosted git repository.

hapylestat pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-2.7 by this push:
     new 027157d  AMBARI-25612. Ambari stops alert notices dispatching on unhandled exception inside. (dvitiuk via dgrinenko) (#3280)
027157d is described below

commit 027157d86a1b3b070487d90f9a797e6ffbb3ea80
Author: dvitiiuk <dm...@gmail.com>
AuthorDate: Tue Jan 26 13:57:33 2021 +0200

    AMBARI-25612. Ambari stops alert notices dispatching on unhandled exception inside. (dvitiuk via dgrinenko) (#3280)
---
 .../state/services/AlertNoticeDispatchService.java | 176 ++++++++++++---------
 1 file changed, 105 insertions(+), 71 deletions(-)

diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
index c7de5d0..60e53a5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
@@ -271,16 +271,51 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
    */
   @Override
   protected void runOneIteration() throws Exception {
+    Map<AlertTargetEntity, List<AlertNoticeEntity>> aggregateMap;
+    try {
+      aggregateMap = getGroupedNotices();
+    } catch (Exception e) {
+      LOG.error("Caught exception during alert notices preparing.", e);
+      return;
+    }
+
+    // now that all of the notices are grouped by target, dispatch them
+    Set<AlertTargetEntity> targets = aggregateMap.keySet();
+    for (AlertTargetEntity target : targets) {
+      List<AlertNoticeEntity> notices = aggregateMap.get(target);
+      if (null == notices || notices.size() == 0) {
+        continue;
+      }
+      try {
+        String targetType = target.getNotificationType();
+        NotificationDispatcher dispatcher = m_dispatchFactory.getDispatcher(targetType);
+
+        // create a single digest notification if supported
+        if (dispatcher.isDigestSupported()) {
+          createSingleNotice(dispatcher, target, notices);
+        } else {
+          createSeparateNotices(dispatcher, target, notices);
+        }
+      } catch (Exception e) {
+        LOG.error("Caught exception during Alert Notice dispatching.", e);
+      }
+    }
+  }
+
+  /**
+   * Retrieves all pending notices to dispatch and groups them by target.
+   * @return grouped notices.
+   */
+  private Map<AlertTargetEntity, List<AlertNoticeEntity>> getGroupedNotices() {
     List<AlertNoticeEntity> pending = m_dao.findPendingNotices();
     if (pending.size() == 0) {
-      return;
+      return Collections.EMPTY_MAP;
     }
 
     LOG.info("There are {} pending alert notices about to be dispatched...",
         pending.size());
 
-    Map<AlertTargetEntity, List<AlertNoticeEntity>> aggregateMap =
-      new HashMap<>(pending.size());
+    Map<AlertTargetEntity, List<AlertNoticeEntity>> aggregateMap = new HashMap<>(pending.size());
 
     // combine all histories by target
     for (AlertNoticeEntity notice : pending) {
@@ -298,77 +333,76 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
 
       notices.add(notice);
     }
+    return aggregateMap;
+  }
 
-    // now that all of the notices are grouped by target, dispatch them
-    Set<AlertTargetEntity> targets = aggregateMap.keySet();
-    for (AlertTargetEntity target : targets) {
-      List<AlertNoticeEntity> notices = aggregateMap.get(target);
-      if (null == notices || notices.size() == 0) {
-        continue;
-      }
+  /**
+   * Creates a single digest notification. Should be used when dispatcher supports digest.
+   * @param dispatcher dispatches the created notifications.
+   * @param target where notifications will be sent.
+   * @param notices notices should be dispatched.
+   */
+  private void createSingleNotice(NotificationDispatcher dispatcher, AlertTargetEntity target,
+                                           List<AlertNoticeEntity> notices) {
+    AlertNotification notification = buildNotificationFromTarget(target);
+    notification.CallbackIds = new ArrayList<>(notices.size());
+    List<AlertHistoryEntity> histories = new ArrayList<>(
+        notices.size());
+
+    // add callback IDs so that the notices can be marked as DELIVERED or
+    // FAILED, and create a list of just the alert histories
+    for (AlertNoticeEntity notice : notices) {
+      AlertHistoryEntity history = notice.getAlertHistory();
+      histories.add(history);
+
+      notification.CallbackIds.add(notice.getUuid());
+    }
+
+
+    // populate the subject and body fields; if there is a problem
+    // generating the content, then mark the notices as FAILED
+    try {
+      renderDigestNotificationContent(dispatcher, notification, histories, target);
+
+      // dispatch
+      DispatchRunnable runnable = new DispatchRunnable(dispatcher, notification);
+      m_executor.execute(runnable);
+    } catch (Exception exception) {
+      LOG.error("Unable to create notification for alerts", exception);
+
+      // there was a problem generating content for the target; mark all
+      // notices as FAILED and skip this target
+      // mark these as failed
+      notification.Callback.onFailure(notification.CallbackIds);
+    }
+  }
+
+  /**
+   * If the dispatcher does not support digest, each notice must have a 1:1 notification created for it.
+   * @param dispatcher dispatches the created notifications.
+   * @param target where notifications will be sent.
+   * @param notices notices should be dispatched.
+   */
+  private void createSeparateNotices(NotificationDispatcher dispatcher, AlertTargetEntity target,
+                                      List<AlertNoticeEntity> notices) {
+    for (AlertNoticeEntity notice : notices) {
+      AlertNotification notification = buildNotificationFromTarget(target);
+      AlertHistoryEntity history = notice.getAlertHistory();
+      notification.CallbackIds = Collections.singletonList(notice.getUuid());
+
+      // populate the subject and body fields; if there is a problem
+      // generating the content, then mark the notices as FAILED
       try {
-        String targetType = target.getNotificationType();
-        NotificationDispatcher dispatcher = m_dispatchFactory.getDispatcher(targetType);
+        renderNotificationContent(dispatcher, notification, history, target);
 
-        // create a single digest notification if supported
-        if (dispatcher.isDigestSupported()) {
-          AlertNotification notification = buildNotificationFromTarget(target);
-          notification.CallbackIds = new ArrayList<>(notices.size());
-          List<AlertHistoryEntity> histories = new ArrayList<>(
-                  notices.size());
-
-          // add callback IDs so that the notices can be marked as DELIVERED or
-          // FAILED, and create a list of just the alert histories
-          for (AlertNoticeEntity notice : notices) {
-            AlertHistoryEntity history = notice.getAlertHistory();
-            histories.add(history);
-
-            notification.CallbackIds.add(notice.getUuid());
-          }
-
-
-          // populate the subject and body fields; if there is a problem
-          // generating the content, then mark the notices as FAILED
-          try {
-            renderDigestNotificationContent(dispatcher, notification, histories, target);
-
-            // dispatch
-            DispatchRunnable runnable = new DispatchRunnable(dispatcher, notification);
-            m_executor.execute(runnable);
-          } catch (Exception exception) {
-            LOG.error("Unable to create notification for alerts", exception);
-
-            // there was a problem generating content for the target; mark all
-            // notices as FAILED and skip this target
-            // mark these as failed
-            notification.Callback.onFailure(notification.CallbackIds);
-          }
-        } else {
-          // the dispatcher does not support digest, each notice must have a 1:1
-          // notification created for it
-          for (AlertNoticeEntity notice : notices) {
-            AlertNotification notification = buildNotificationFromTarget(target);
-            AlertHistoryEntity history = notice.getAlertHistory();
-            notification.CallbackIds = Collections.singletonList(notice.getUuid());
-
-            // populate the subject and body fields; if there is a problem
-            // generating the content, then mark the notices as FAILED
-            try {
-              renderNotificationContent(dispatcher, notification, history, target);
-
-              // dispatch
-              DispatchRunnable runnable = new DispatchRunnable(dispatcher, notification);
-              m_executor.execute(runnable);
-            } catch (Exception exception) {
-              LOG.error("Unable to create notification for alert", exception);
-
-              // mark these as failed
-              notification.Callback.onFailure(notification.CallbackIds);
-            }
-          }
-        }
-      } catch (Exception e) {
-        LOG.error("Caught exception during Alert Notice dispatching.", e);
+        // dispatch
+        DispatchRunnable runnable = new DispatchRunnable(dispatcher, notification);
+        m_executor.execute(runnable);
+      } catch (Exception exception) {
+        LOG.error("Unable to create notification for alert", exception);
+
+        // mark these as failed
+        notification.Callback.onFailure(notification.CallbackIds);
       }
     }
   }