You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ak...@apache.org on 2019/07/09 18:22:16 UTC

[incubator-pinot] branch master updated: [TE] Make email template and subject pluggable under email alert scheme (#4409)

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

akshayrai09 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new de62d8e  [TE] Make email template and subject pluggable under email alert scheme (#4409)
de62d8e is described below

commit de62d8e15557e251cfd3a615828ef65009ea0b7a
Author: Akshay Rai <ak...@gmail.com>
AuthorDate: Tue Jul 9 11:22:10 2019 -0700

    [TE] Make email template and subject pluggable under email alert scheme (#4409)
---
 .../alert/scheme/DetectionEmailAlerter.java        | 60 +++++++++++++++++++---
 .../translator/SubscriptionConfigTranslator.java   |  6 +--
 .../thirdeye/detection/yaml/YamlResourceTest.java  |  3 ++
 .../detection/yaml/alertconfig/alert-config-5.yaml |  3 ++
 4 files changed, 62 insertions(+), 10 deletions(-)

diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/alert/scheme/DetectionEmailAlerter.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/alert/scheme/DetectionEmailAlerter.java
index 0367244..d95b0ad 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/alert/scheme/DetectionEmailAlerter.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/alert/scheme/DetectionEmailAlerter.java
@@ -31,6 +31,7 @@ import org.apache.pinot.thirdeye.anomalydetection.context.AnomalyResult;
 import org.apache.pinot.thirdeye.datalayer.dto.AlertConfigDTO;
 import org.apache.pinot.thirdeye.datalayer.dto.DetectionAlertConfigDTO;
 import org.apache.pinot.thirdeye.datalayer.dto.MergedAnomalyResultDTO;
+import org.apache.pinot.thirdeye.datalayer.pojo.AlertConfigBean;
 import org.apache.pinot.thirdeye.detection.ConfigUtils;
 import org.apache.pinot.thirdeye.detection.alert.AlertUtils;
 import org.apache.pinot.thirdeye.detection.alert.DetectionAlertFilterRecipients;
@@ -61,7 +62,11 @@ public class DetectionEmailAlerter extends DetectionAlertScheme {
   private static final Comparator<AnomalyResult> COMPARATOR_DESC =
       (o1, o2) -> -1 * Long.compare(o1.getStartTime(), o2.getStartTime());
   private static final String DEFAULT_EMAIL_FORMATTER_TYPE = "MultipleAnomaliesEmailContentFormatter";
+  private static final String ENTITY_REPORT_FORMATTER_TYPE = "EntityContentFormatter";
   private static final String EMAIL_WHITELIST_KEY = "emailWhitelist";
+  private static final String PROP_EMAIL_SCHEME = "emailScheme";
+  private static final String PROP_EMAIL_TEMPLATE = "template";
+  private static final String PROP_EMAIL_SUBJECT_STYLE = "subject";
 
   private ThirdEyeAnomalyConfiguration teConfig;
 
@@ -124,24 +129,65 @@ public class DetectionEmailAlerter extends DetectionAlertScheme {
     LOG.info("Email sent with subject '{}' to {} recipients", email.getSubject(), recipientCount);
   }
 
+  public enum EmailTemplate {
+    DEFAULT_EMAIL,
+    ENTITY_REPORT
+  }
+
+  /**
+   * Plug the appropriate template based on configuration.
+   */
+  private static EmailContentFormatter makeTemplate(Map<String, Object> emailParams) throws Exception {
+    EmailTemplate template = EmailTemplate.DEFAULT_EMAIL;
+    if (emailParams != null && emailParams.containsKey(PROP_EMAIL_TEMPLATE)) {
+      template = EmailTemplate.valueOf(emailParams.get(PROP_EMAIL_TEMPLATE).toString());
+    }
+
+    switch (template) {
+      case DEFAULT_EMAIL:
+        LOG.info("Using the " + DEFAULT_EMAIL_FORMATTER_TYPE + " email template.");
+        return EmailContentFormatterFactory.fromClassName(DEFAULT_EMAIL_FORMATTER_TYPE);
+
+      case ENTITY_REPORT:
+        LOG.info("Using the " + template + " email template.");
+        return EmailContentFormatterFactory.fromClassName(ENTITY_REPORT_FORMATTER_TYPE);
+
+      default:
+        throw new IllegalArgumentException(String.format("Unknown type '%s'", template));
+    }
+  }
+
+  /**
+   * Plug the appropriate email subject style based on configuration
+   */
+  private AlertConfigBean.SubjectType makeSubject(Map<String, Object> emailParams) {
+    AlertConfigBean.SubjectType subjectType;
+    if (emailParams != null && emailParams.containsKey(PROP_EMAIL_SUBJECT_STYLE)) {
+      subjectType = AlertConfigBean.SubjectType.valueOf(emailParams.get(PROP_EMAIL_SUBJECT_STYLE).toString());
+    } else {
+      // To support the legacy email subject configuration
+      subjectType = this.config.getSubjectType();
+    }
+
+    return subjectType;
+  }
+
   private void sendEmail(DetectionAlertFilterRecipients recipients, Set<MergedAnomalyResultDTO> anomalies) throws Exception {
     whitelistRecipients(recipients);
     validateAlert(recipients, anomalies);
 
-    EmailContentFormatter emailContentFormatter =
-        EmailContentFormatterFactory.fromClassName(DEFAULT_EMAIL_FORMATTER_TYPE);
-
+    Map<String, Object> emailParams = ConfigUtils.getMap(this.config.getAlertSchemes().get(PROP_EMAIL_SCHEME));
+    EmailContentFormatter emailContentFormatter = makeTemplate(emailParams);
     emailContentFormatter.init(new Properties(),
         EmailContentFormatterConfiguration.fromThirdEyeAnomalyConfiguration(this.teConfig));
 
-    List<AnomalyResult> anomalyResultListOfGroup = new ArrayList<>();
-    anomalyResultListOfGroup.addAll(anomalies);
-    Collections.sort(anomalyResultListOfGroup, COMPARATOR_DESC);
+    List<AnomalyResult> anomalyResultListOfGroup = new ArrayList<>(anomalies);
+    anomalyResultListOfGroup.sort(COMPARATOR_DESC);
 
     AlertConfigDTO alertConfig = new AlertConfigDTO();
     alertConfig.setName(this.config.getName());
     alertConfig.setFromAddress(this.config.getFrom());
-    alertConfig.setSubjectType(this.config.getSubjectType());
+    alertConfig.setSubjectType(makeSubject(emailParams));
     alertConfig.setReferenceLinks(this.config.getReferenceLinks());
 
     EmailEntity emailEntity = emailContentFormatter.getEmailEntity(alertConfig, null,
diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/SubscriptionConfigTranslator.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/SubscriptionConfigTranslator.java
index bc037ca..d7416e1 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/SubscriptionConfigTranslator.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/SubscriptionConfigTranslator.java
@@ -20,6 +20,7 @@
 package org.apache.pinot.thirdeye.detection.yaml.translator;
 
 import com.google.common.base.CaseFormat;
+import com.google.common.base.Preconditions;
 import java.util.stream.Collectors;
 import org.apache.pinot.thirdeye.datalayer.bao.DetectionConfigManager;
 import org.apache.pinot.thirdeye.datalayer.dto.DetectionAlertConfigDTO;
@@ -141,10 +142,9 @@ public class SubscriptionConfigTranslator extends ConfigTranslator<DetectionAler
     Map<String, Object> alertSchemesParsed = new HashMap<>();
     if (!alertSchemes.isEmpty()) {
       for (Map<String, Object> alertScheme : alertSchemes) {
-        if (alertScheme.get(PROP_TYPE) != null) {
-          alertSchemesParsed.put(PROP_CLASS_NAME,
+        Preconditions.checkNotNull(alertScheme.get(PROP_TYPE));
+        alertSchemesParsed.put(PROP_CLASS_NAME,
               DETECTION_ALERT_REGISTRY.lookupAlertSchemes(alertScheme.get(PROP_TYPE).toString()));
-        }
 
         if (alertScheme.get(PROP_PARAM) != null) {
           for (Map.Entry<String, Object> params : ((Map<String, Object>) alertScheme.get(PROP_PARAM)).entrySet()) {
diff --git a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/yaml/YamlResourceTest.java b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/yaml/YamlResourceTest.java
index 621685c..4af7323 100644
--- a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/yaml/YamlResourceTest.java
+++ b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/yaml/YamlResourceTest.java
@@ -239,6 +239,9 @@ public class YamlResourceTest {
       Assert.assertNotNull(alertDTO);
       Assert.assertEquals(alertDTO.getName(), "Subscription Group Name");
       Assert.assertEquals(alertDTO.getApplication(), "test_application");
+      Assert.assertNotNull(alertDTO.getAlertSchemes().get("emailScheme"));
+      Assert.assertEquals(alertDTO.getAlertSchemes().get("emailScheme").get("template"), "ENTITY_REPORT");
+      Assert.assertEquals(alertDTO.getAlertSchemes().get("emailScheme").get("subject"), "METRICS");
 
       // Verify if the vector clock is updated with the updated detection
       Assert.assertEquals(alertDTO.getVectorClocks().keySet().size(), 1);
diff --git a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/alertconfig/alert-config-5.yaml b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/alertconfig/alert-config-5.yaml
index ffa241c..9e7517d 100644
--- a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/alertconfig/alert-config-5.yaml
+++ b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/alertconfig/alert-config-5.yaml
@@ -23,6 +23,9 @@ recipients:
 
 alertSchemes:
 - type: EMAIL
+  params:
+    template: ENTITY_REPORT
+    subject: METRICS
 - type: IRIS
   params:
     plan: thirdye_test_plan


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org