You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ji...@apache.org on 2019/02/12 18:23:51 UTC

[incubator-pinot] branch master updated: [TE] yaml - error messages (#3816)

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

jihao 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 eb0d5b6  [TE] yaml - error messages (#3816)
eb0d5b6 is described below

commit eb0d5b68e4a48789192416d0817c2de6b2b4d470
Author: Jihao Zhang <ji...@linkedin.com>
AuthorDate: Tue Feb 12 10:23:46 2019 -0800

    [TE] yaml - error messages (#3816)
    
    * Provide error messages in detection pipeline
    * Fix detection subscription group end point
    * Vlidators refactor
---
 .../thirdeye/detection/DetectionPipeline.java      |   2 +-
 .../thirdeye/detection/DetectionResource.java      |   2 +-
 .../detection/validators/ConfigValidator.java      |  53 ++++-------
 .../validators/DetectionConfigValidator.java       |  30 ++----
 .../validators/SubscriptionConfigValidator.java    |  14 +--
 .../thirdeye/detection/yaml/YamlResource.java      | 101 ++++++++++++---------
 .../thirdeye/detection/yaml/YamlResourceTest.java  |   4 +-
 7 files changed, 95 insertions(+), 111 deletions(-)

diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionPipeline.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionPipeline.java
index 69836db..d8b2d66 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionPipeline.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionPipeline.java
@@ -69,7 +69,7 @@ public abstract class DetectionPipeline {
     try {
       this.initComponents();
     } catch (Exception e) {
-      throw new IllegalArgumentException("Initialize components failed. Please check rule parameters.", e);
+      throw new IllegalArgumentException("Initialize components failed. Please check rule parameters. " + e.getMessage());
     }
   }
 
diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionResource.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionResource.java
index 7bc737b..e3d7de7 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionResource.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionResource.java
@@ -142,7 +142,7 @@ public class DetectionResource {
     List<DetectionAlertConfigDTO> detectionAlertConfigDTOs = this.detectionAlertConfigDAO.findAll();
     Set<DetectionAlertConfigDTO> subscriptionGroupAlertDTOs = new HashSet<>();
     for (DetectionAlertConfigDTO alertConfigDTO : detectionAlertConfigDTOs){
-      if (alertConfigDTO.getVectorClocks().containsKey(id)){
+      if (alertConfigDTO.getVectorClocks().containsKey(id) || ConfigUtils.getLongs(alertConfigDTO.getProperties().get("detectionConfigIds")).contains(id)){
         subscriptionGroupAlertDTOs.add(alertConfigDTO);
       }
     }
diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/ConfigValidator.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/ConfigValidator.java
index aa5be6f..007353a 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/ConfigValidator.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/ConfigValidator.java
@@ -20,45 +20,26 @@
 package org.apache.pinot.thirdeye.detection.validators;
 
 import javax.xml.bind.ValidationException;
-import org.apache.pinot.thirdeye.datalayer.bao.AlertConfigManager;
-import org.apache.pinot.thirdeye.datalayer.bao.ApplicationManager;
-import org.apache.pinot.thirdeye.datasource.DAORegistry;
-import java.util.Map;
-import org.apache.commons.lang.StringUtils;
-import org.yaml.snakeyaml.Yaml;
+import org.apache.pinot.thirdeye.datalayer.dto.AbstractDTO;
 
 
-public abstract class ConfigValidator {
-
-  protected static final Yaml YAML = new Yaml();
-
-  final AlertConfigManager alertDAO;
-  final ApplicationManager applicationDAO;
-
-  ConfigValidator() {
-    this.alertDAO = DAORegistry.getInstance().getAlertConfigDAO();
-    this.applicationDAO = DAORegistry.getInstance().getApplicationDAO();
-  }
-
+/**
+ * Validate a config
+ * @param <T> the type of the config
+ */
+interface ConfigValidator<T extends AbstractDTO> {
   /**
-   * Perform basic validations on a yaml file like verifying if
-   * the yaml exists and is parsable
+   * Validate the configuration. Thrown a validation exception if validation failed.
+   * @param config the config
+   * @throws ValidationException the validation exception with error message
    */
-  @SuppressWarnings("unchecked")
-  public boolean validateYAMLConfig(String yamlConfig) throws ValidationException {
-    // Check if YAML is empty or not
-    if (StringUtils.isEmpty(yamlConfig)) {
-      throw new ValidationException("The Yaml Payload in the request is empty.");
-    }
-
-    // Check if the YAML is parsable
-    try {
-      Map<String, Object> yamlConfigMap = (Map<String, Object>) YAML.load(yamlConfig);
-    } catch (Exception e) {
-      throw new ValidationException("Error parsing the Yaml payload. Check for syntax issues.");
-    }
-
-    return true;
-  }
+  void validateConfig(T config) throws ValidationException;
 
+  /**
+   * Validate the configuration. Thrown a validation exception if validation failed.
+   * @param updatedConfig the new config
+   * @param oldConfig the old config
+   * @throws ValidationException the validation exception with error message
+   */
+  void validateUpdatedConfig(T updatedConfig, T oldConfig) throws ValidationException;
 }
diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidator.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidator.java
index b94f70d..adadad7 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidator.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidator.java
@@ -19,6 +19,7 @@
 
 package org.apache.pinot.thirdeye.detection.validators;
 
+import com.google.common.base.Preconditions;
 import javax.xml.bind.ValidationException;
 import org.apache.pinot.thirdeye.datalayer.bao.DatasetConfigManager;
 import org.apache.pinot.thirdeye.datalayer.bao.MetricConfigManager;
@@ -32,26 +33,14 @@ import org.apache.pinot.thirdeye.datasource.loader.TimeSeriesLoader;
 import org.apache.pinot.thirdeye.detection.DataProvider;
 import org.apache.pinot.thirdeye.detection.DefaultDataProvider;
 import org.apache.pinot.thirdeye.detection.DetectionPipelineLoader;
-import org.apache.pinot.thirdeye.detection.yaml.YamlDetectionAlertConfigTranslator;
-import org.apache.pinot.thirdeye.detection.yaml.YamlDetectionTranslatorLoader;
-import org.yaml.snakeyaml.Yaml;
 
 
-public class DetectionConfigValidator extends ConfigValidator {
-
-  private static DetectionConfigValidator INSTANCE;
+public class DetectionConfigValidator implements ConfigValidator<DetectionConfigDTO> {
 
   private final DataProvider provider;
   private final DetectionPipelineLoader loader;
 
-  public static DetectionConfigValidator getInstance() {
-    if (INSTANCE == null) {
-      INSTANCE = new DetectionConfigValidator();
-    }
-    return INSTANCE;
-  }
-
-  DetectionConfigValidator() {
+  public DetectionConfigValidator() {
     MetricConfigManager metricDAO = DAORegistry.getInstance().getMetricConfigDAO();
     DatasetConfigManager datasetDAO = DAORegistry.getInstance().getDatasetConfigDAO();
 
@@ -84,28 +73,29 @@ public class DetectionConfigValidator extends ConfigValidator {
 
       // set id back
       detectionConfig.setId(id);
-    } catch (Exception e) {
-      throw new ValidationException("Semantic error while initializing the detection pipeline.", e.getMessage());
+    } catch (Exception e){
+      // exception thrown in validate pipeline via reflection
+      throw new ValidationException("Semantic error: " + e.getCause().getMessage());
     }
   }
 
   /**
    * Perform validation on the detection config like verifying if all the required fields are set
    */
+  @Override
   public void validateConfig(DetectionConfigDTO detectionConfig) throws ValidationException {
     semanticValidation(detectionConfig);
-
-    // TODO: Add more static validations here
   }
 
   /**
    * Perform validation on the updated detection config. Check for fields which shouldn't be
    * updated by the user.
    */
+  @Override
   public void validateUpdatedConfig(DetectionConfigDTO updatedConfig, DetectionConfigDTO oldConfig)
       throws ValidationException {
     validateConfig(updatedConfig);
-
-    // TODO: Add more checks here
+    Preconditions.checkArgument(updatedConfig.getId().equals(oldConfig.getId()));
+    Preconditions.checkArgument(updatedConfig.getLastTimestamp() == oldConfig.getLastTimestamp());
   }
 }
diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/SubscriptionConfigValidator.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/SubscriptionConfigValidator.java
index 34bdba9..909e50b 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/SubscriptionConfigValidator.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/validators/SubscriptionConfigValidator.java
@@ -19,30 +19,25 @@
 
 package org.apache.pinot.thirdeye.detection.validators;
 
-import javax.xml.bind.ValidationException;
-import org.apache.pinot.thirdeye.datalayer.dto.DetectionAlertConfigDTO;
 import java.util.List;
 import java.util.Map;
+import javax.xml.bind.ValidationException;
 import org.apache.commons.lang.StringUtils;
-import org.apache.pinot.thirdeye.datalayer.util.Predicate;
+import org.apache.pinot.thirdeye.datalayer.dto.DetectionAlertConfigDTO;
 import org.apache.pinot.thirdeye.datasource.DAORegistry;
 import org.apache.pinot.thirdeye.detection.ConfigUtils;
 
 import static org.apache.pinot.thirdeye.detection.yaml.YamlDetectionAlertConfigTranslator.*;
 
 
-public class SubscriptionConfigValidator extends ConfigValidator {
+public class SubscriptionConfigValidator implements ConfigValidator<DetectionAlertConfigDTO> {
 
-  private static final SubscriptionConfigValidator INSTANCE = new SubscriptionConfigValidator();
   private static final String PROP_CLASS_NAME = "className";
 
-  public static SubscriptionConfigValidator getInstance() {
-    return INSTANCE;
-  }
-
   /**
    * Perform validation on the alert config like verifying if all the required fields are set
    */
+  @Override
   public void validateConfig(DetectionAlertConfigDTO alertConfig) throws ValidationException {
     // Check for all the required fields in the alert
     if (StringUtils.isEmpty(alertConfig.getName())) {
@@ -93,6 +88,7 @@ public class SubscriptionConfigValidator extends ConfigValidator {
    * Perform validation on the updated alert config. Check for fields which shouldn't be
    * updated by the user.
    */
+  @Override
   public void validateUpdatedConfig(DetectionAlertConfigDTO updatedAlertConfig, DetectionAlertConfigDTO oldAlertConfig)
       throws ValidationException {
     validateConfig(updatedAlertConfig);
diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/YamlResource.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/YamlResource.java
index 4c5f277..b1dc8db 100644
--- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/YamlResource.java
+++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/YamlResource.java
@@ -85,6 +85,8 @@ public class YamlResource {
   private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
   private static final String PROP_SUBS_GROUP_NAME = "subscriptionGroupName";
+
+  // default onboarding replay period
   private static final long ONBOARDING_REPLAY_LOOKBACK = TimeUnit.DAYS.toMillis(30);
 
   private final DetectionConfigManager detectionConfigDAO;
@@ -106,8 +108,8 @@ public class YamlResource {
     this.detectionConfigDAO = DAORegistry.getInstance().getDetectionConfigManager();
     this.detectionAlertConfigDAO = DAORegistry.getInstance().getDetectionAlertConfigManager();
     this.translatorLoader = new YamlDetectionTranslatorLoader();
-    this.detectionValidator = DetectionConfigValidator.getInstance();
-    this.subscriptionValidator = SubscriptionConfigValidator.getInstance();
+    this.detectionValidator = new DetectionConfigValidator();
+    this.subscriptionValidator = new SubscriptionConfigValidator();
     this.alertConfigTranslator = new YamlDetectionAlertConfigTranslator(this.detectionConfigDAO);
     this.metricDAO = DAORegistry.getInstance().getMetricConfigDAO();
     this.datasetDAO = DAORegistry.getInstance().getDatasetConfigDAO();
@@ -188,10 +190,10 @@ public class YamlResource {
   @ApiOperation("Use yaml to create both subscription and detection yaml. ")
   public Response createYamlAlert(@ApiParam(value =  "a json contains both subscription and detection yaml as string")  String payload,
       @ApiParam("tuning window start time for tunable components") @QueryParam("startTime") long startTime,
-      @ApiParam("tuning window end time for tunable components") @QueryParam("endTime") long endTime) throws Exception{
+      @ApiParam("tuning window end time for tunable components") @QueryParam("endTime") long endTime) throws Exception {
     Map<String, String> yamls = OBJECT_MAPPER.readValue(payload, Map.class);
     if (StringUtils.isBlank(payload)){
-      return Response.status(Response.Status.BAD_REQUEST).entity(ImmutableMap.of("message", "Empty payload")).build();
+      return Response.status(Response.Status.BAD_REQUEST).entity(ImmutableMap.of("message", "The Yaml Payload in the request is empty.")).build();
     }
     if (!yamls.containsKey("detection")) {
       return Response.status(Response.Status.BAD_REQUEST).entity(ImmutableMap.of("message", "detection pipeline yaml is missing")).build();
@@ -201,8 +203,17 @@ public class YamlResource {
     }
 
     // Detection
-    String detectionYaml = yamls.get("detection");
-    long detectionConfigId = createDetectionPipeline(detectionYaml, startTime, endTime);
+    long detectionConfigId;
+    try {
+      detectionConfigId = createDetectionPipeline(yamls.get("detection"), startTime, endTime);
+    } catch (ValidationException e) {
+      LOG.warn("Validation error while creating detection pipeline with payload " + payload, e);
+      return Response.status(Response.Status.BAD_REQUEST).entity(ImmutableMap.of("message", "Validation Error! " + e.getMessage())).build();
+    } catch (Exception e) {
+      LOG.error("Error creating detection pipeline with payload " + payload, e);
+      return Response.serverError().entity(ImmutableMap.of("message", "Failed to create the detection pipeline. Reach out to the ThirdEye team.",
+          "more-info", "Error = " + e.getMessage())).build();
+    }
 
     // Notification
     String notificationYaml = yamls.get("notification");
@@ -211,40 +222,45 @@ public class YamlResource {
     try {
       notificationYamlConfig = ConfigUtils.getMap(this.yaml.load(notificationYaml));
     } catch (Exception e){
+      this.detectionConfigDAO.deleteById(detectionConfigId);
       return Response.status(Response.Status.BAD_REQUEST)
           .entity(ImmutableMap.of("message", "notification yaml parsing error, " + e.getMessage())).build();
     }
 
     // Check if existing or new subscription group
     String groupName = MapUtils.getString(notificationYamlConfig, PROP_SUBS_GROUP_NAME);
-    List<DetectionAlertConfigDTO> alertConfigDTOS = detectionAlertConfigDAO
-        .findByPredicate(Predicate.EQ("name", groupName));
+    List<DetectionAlertConfigDTO> alertConfigDTOS = detectionAlertConfigDAO.findByPredicate(Predicate.EQ("name", groupName));
     Response response;
     if (!alertConfigDTOS.isEmpty()) {
       response = updateSubscriptionGroupApi(notificationYaml, alertConfigDTOS.get(0).getId());
     } else {
       response = createSubscriptionGroupApi(notificationYaml);
     }
-
     if (response.getStatusInfo() != Response.Status.OK) {
       // revert detection DTO
       this.detectionConfigDAO.deleteById(detectionConfigId);
-      return Response.serverError().entity(response.getEntity()).build();
+      return response;
     }
-    long alertId = Long.parseLong(ConfigUtils.getMap(response.getEntity()).get("detectionAlertConfigId").toString());
+
     // create an yaml onboarding task to run replay and tuning
     createYamlOnboardingTask(detectionConfigId, startTime, endTime);
+
+    long alertId = Long.parseLong(ConfigUtils.getMap(response.getEntity()).get("detectionAlertConfigId").toString());
     return Response.ok().entity(ImmutableMap.of("detectionConfigId", detectionConfigId, "detectionAlertConfigId", alertId)).build();
   }
 
-  long createDetectionPipeline(String yamlDetectionConfig, long startTime, long endTime) throws Exception {
-    detectionValidator.validateYAMLConfig(yamlDetectionConfig);
-
-    // Translate config from YAML to detection config (JSON)
-    TreeMap<String, Object> newDetectionConfigMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-    newDetectionConfigMap.putAll(ConfigUtils.getMap(this.yaml.load(yamlDetectionConfig)));
-    DetectionConfigDTO detectionConfig = buildDetectionConfigFromYaml(startTime, endTime, newDetectionConfigMap, null);
-    detectionConfig.setYaml(yamlDetectionConfig);
+  long createDetectionPipeline(String yamlDetectionConfig, long startTime, long endTime) throws ValidationException {
+    DetectionConfigDTO detectionConfig;
+    try {
+      Preconditions.checkArgument(StringUtils.isNotBlank(yamlDetectionConfig), "The Yaml Payload in the request is empty.");
+      // Translate config from YAML to detection config (JSON)
+      Map<String, Object> newDetectionConfigMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+      newDetectionConfigMap.putAll(ConfigUtils.getMap(this.yaml.load(yamlDetectionConfig)));
+      detectionConfig = buildDetectionConfigFromYaml(startTime, endTime, newDetectionConfigMap, null);
+      detectionConfig.setYaml(yamlDetectionConfig);
+    } catch (Exception e) {
+      throw new ValidationException(e.getMessage());
+    }
 
     // Check for duplicates
     List<DetectionConfigDTO> detectionConfigDTOS = detectionConfigDAO
@@ -253,9 +269,8 @@ public class YamlResource {
       throw new ValidationException("Detection name is already taken. Please use a different detectionName.");
     }
 
-    // Validate the config before saving it
+    // Validate the detection config before saving it
     detectionValidator.validateConfig(detectionConfig);
-
     // Save the detection config
     Preconditions.checkNotNull(detectionConfig);
     Long id = this.detectionConfigDAO.save(detectionConfig);
@@ -286,10 +301,10 @@ public class YamlResource {
     } catch (ValidationException e) {
       LOG.warn("Validation error while creating detection pipeline with payload " + payload, e);
       responseMessage.put("message", "Validation Error! " + e.getMessage());
-      return Response.serverError().entity(responseMessage).build();
+      return Response.status(Response.Status.BAD_REQUEST).entity(responseMessage).build();
     } catch (Exception e) {
-      LOG.error("Error creating subscription group with payload " + payload, e);
-      responseMessage.put("message", "Failed to create the subscription group. Reach out to the ThirdEye team.");
+      LOG.error("Error creating detection pipeline with payload " + payload, e);
+      responseMessage.put("message", "Failed to create the detection pipeline. Reach out to the ThirdEye team.");
       responseMessage.put("more-info", "Error = " + e.getMessage());
       return Response.serverError().entity(responseMessage).build();
     }
@@ -302,20 +317,22 @@ public class YamlResource {
 
   void updateDetectionPipeline(long detectionID, String yamlDetectionConfig, long startTime, long endTime) throws Exception {
     DetectionConfigDTO existingDetectionConfig = this.detectionConfigDAO.findById(detectionID);
+    DetectionConfigDTO detectionConfig;
     if (existingDetectionConfig == null) {
-      throw new RuntimeException("Cannot find detection pipeline " + detectionID);
+      throw new ValidationException("Cannot find detection pipeline " + detectionID);
+    }
+    try {
+      Preconditions.checkArgument(StringUtils.isNotBlank(yamlDetectionConfig), "The Yaml Payload in the request is empty.");
+      // Translate config from YAML to detection config (JSON)
+      TreeMap<String, Object> newDetectionConfigMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+      newDetectionConfigMap.putAll(ConfigUtils.getMap(this.yaml.load(yamlDetectionConfig)));
+      detectionConfig = buildDetectionConfigFromYaml(startTime, endTime, newDetectionConfigMap, existingDetectionConfig);
+      detectionConfig.setYaml(yamlDetectionConfig);
+    } catch (Exception e) {
+      throw new ValidationException(e.getMessage());
     }
-    detectionValidator.validateYAMLConfig(yamlDetectionConfig);
-
-    // Translate config from YAML to detection config (JSON)
-    TreeMap<String, Object> newDetectionConfigMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-    newDetectionConfigMap.putAll(ConfigUtils.getMap(this.yaml.load(yamlDetectionConfig)));
-    DetectionConfigDTO detectionConfig = buildDetectionConfigFromYaml(startTime, endTime, newDetectionConfigMap, existingDetectionConfig);
-    detectionConfig.setYaml(yamlDetectionConfig);
-
     // Validate updated config before saving it
     detectionValidator.validateUpdatedConfig(detectionConfig, existingDetectionConfig);
-
     // Save the detection config
     Preconditions.checkNotNull(detectionConfig);
     Long id = this.detectionConfigDAO.save(detectionConfig);
@@ -346,22 +363,22 @@ public class YamlResource {
     } catch (ValidationException e) {
       LOG.warn("Validation error while creating detection pipeline with payload " + payload, e);
       responseMessage.put("message", "Validation Error! " + e.getMessage());
-      return Response.serverError().entity(responseMessage).build();
+      return Response.status(Response.Status.BAD_REQUEST).entity(responseMessage).build();
     } catch (Exception e) {
-      LOG.error("Error creating subscription group with payload " + payload, e);
+      LOG.error("Error creating detection pipeline with payload " + payload, e);
       responseMessage.put("message", "Failed to create the subscription group. Reach out to the ThirdEye team.");
       responseMessage.put("more-info", "Error = " + e.getMessage());
       return Response.serverError().entity(responseMessage).build();
     }
 
-    LOG.info("Detection Pipeline " + id + " updated successfully with payload " + payload);
+    LOG.info("Detection Pipeline " + id + " updated successfully");
     responseMessage.put("message", "The detection Pipeline was created successfully.");
     responseMessage.put("detectionConfigId", String.valueOf(id));
     return Response.ok().entity(responseMessage).build();
   }
 
   long createSubscriptionGroup(String yamlAlertConfig) throws ValidationException {
-    subscriptionValidator.validateYAMLConfig(yamlAlertConfig);
+    Preconditions.checkArgument(StringUtils.isNotBlank(yamlAlertConfig), "The Yaml Payload in the request is empty.");
 
     // Translate config from YAML to detection alert config (JSON)
     TreeMap<String, Object> newAlertConfigMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -444,7 +461,7 @@ public class YamlResource {
     if (oldAlertConfig == null) {
       throw new RuntimeException("Cannot find subscription group " + oldAlertConfigID);
     }
-    subscriptionValidator.validateYAMLConfig(yamlAlertConfig);
+    Preconditions.checkArgument(StringUtils.isNotBlank(yamlAlertConfig), "The Yaml Payload in the request is empty.");
 
     // Translate payload to detection alert config
     TreeMap<String, Object> newAlertConfigMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
@@ -487,7 +504,7 @@ public class YamlResource {
       return Response.serverError().entity(responseMessage).build();
     }
 
-    LOG.info("Notification group " + id + " updated successfully with payload " + yamlAlertConfig);
+    LOG.info("Notification group " + id + " updated successfully");
     responseMessage.put("message", "The YAML alert config was updated successfully.");
     responseMessage.put("detectionAlertConfigId", String.valueOf(id));
     return Response.ok().entity(responseMessage).build();
@@ -503,11 +520,11 @@ public class YamlResource {
       @QueryParam("end") long end,
       @QueryParam("tuningStart") long tuningStart,
       @QueryParam("tuningEnd") long tuningEnd,
-      @ApiParam("jsonPayload") String payload) throws Exception {
+      @ApiParam("jsonPayload") String payload) {
     Map<String, String> responseMessage = new HashMap<>();
     DetectionPipelineResult result;
     try {
-      detectionValidator.validateYAMLConfig(payload);
+      Preconditions.checkArgument(StringUtils.isNotBlank(payload), "The Yaml Payload in the request is empty.");
 
       // Translate config from YAML to detection config (JSON)
       Map<String, Object> newDetectionConfigMap = new HashMap<>(ConfigUtils.getMap(this.yaml.load(payload)));
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 a181b5e..9561fcf 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
@@ -61,7 +61,7 @@ public class YamlResourceTest {
       this.yamlResource.createSubscriptionGroup(inValidYaml);
       Assert.fail("Exception not thrown on empty yaml");
     } catch (Exception e) {
-      Assert.assertEquals(e.getMessage(), "Error parsing the Yaml payload. Check for syntax issues.");
+      Assert.assertEquals(e.getMessage(), "Could not parse as map: application:test:application");
     }
 
     String noSubscriptGroupYaml = "application: test_application";
@@ -147,7 +147,7 @@ public class YamlResourceTest {
       this.yamlResource.updateSubscriptionGroup(oldId, inValidYaml);
       Assert.fail("Exception not thrown on empty yaml");
     } catch (Exception e) {
-      Assert.assertEquals(e.getMessage(), "Error parsing the Yaml payload. Check for syntax issues.");
+      Assert.assertEquals(e.getMessage(), "Could not parse as map: application:test:application");
     }
 
     String noSubscriptGroupYaml = "application: test_application";


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