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 8ec8499 [TE] added a couple of validations to check if detection is
subscribed & valid; cleaned up other validations (#5113)
8ec8499 is described below
commit 8ec849968f6025ca471929b6861c0ae1b5f993d0
Author: Akshay Rai <[email protected]>
AuthorDate: Fri Mar 6 09:46:48 2020 -0800
[TE] added a couple of validations to check if detection is subscribed &
valid; cleaned up other validations (#5113)
Validations added:
* Make sure subscription group subscribes to the detectionName while
creating an alert
* Make sure all the subscribed detections are valid
* recipients should be configured under the EMAIL scheme params and not at
the root level
Validations removed:
* type is not compulsory in subscription group
* type is not compulsory for sub-entity alerts.
Added unit tests for newly added validations
---
.../alert/scheme/DetectionEmailAlerter.java | 2 +-
.../validators/DetectionConfigValidator.java | 39 ++++++++--------
.../validators/SubscriptionConfigValidator.java | 52 +++++++++++++++-------
.../thirdeye/detection/yaml/YamlResource.java | 32 ++++++++++++-
.../yaml/translator/DetectionConfigTranslator.java | 4 +-
.../translator/SubscriptionConfigTranslator.java | 3 +-
.../validators/DetectionConfigValidatorTest.java | 9 ----
.../thirdeye/detection/yaml/YamlResourceTest.java | 48 +++++++++++++++++---
.../yaml/detection/detection-config-1.yaml | 2 +-
.../yaml/detection/detection-config-2.yaml | 2 +-
.../yaml/subscription/subscription-config-1.yaml | 15 ++++---
.../yaml/subscription/subscription-config-2.yaml | 14 +++---
.../yaml/subscription/subscription-config-3.yaml | 14 +++---
.../yaml/subscription/subscription-config-4.yaml | 14 +++---
.../yaml/subscription/subscription-config-5.yaml | 13 +++---
.../src/test/resources/sample-alert-config.yml | 14 +++---
16 files changed, 171 insertions(+), 106 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 24177b2..d429125 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
@@ -63,7 +63,7 @@ import static
org.apache.pinot.thirdeye.notification.commons.SmtpConfiguration.S
public class DetectionEmailAlerter extends DetectionAlertScheme {
private static final Logger LOG =
LoggerFactory.getLogger(DetectionEmailAlerter.class);
- private static final String PROP_RECIPIENTS = "recipients";
+ public static final String PROP_RECIPIENTS = "recipients";
private static final String PROP_TO = "to";
private static final String PROP_CC = "cc";
private static final String PROP_BCC = "bcc";
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 8af3462..fbefa5f 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
@@ -21,8 +21,6 @@ package org.apache.pinot.thirdeye.detection.validators;
import com.google.common.base.Preconditions;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -38,6 +36,7 @@ import
org.apache.pinot.thirdeye.detection.DetectionPipelineLoader;
import org.quartz.CronExpression;
import static org.apache.pinot.thirdeye.detection.ConfigUtils.*;
+import static
org.apache.pinot.thirdeye.detection.alert.scheme.DetectionEmailAlerter.*;
public class DetectionConfigValidator implements
ConfigValidator<DetectionConfigDTO> {
@@ -58,6 +57,7 @@ public class DetectionConfigValidator implements
ConfigValidator<DetectionConfig
private static final String PROP_DETECTION_NAME = "detectionName";
private static final String PROP_MAX_DURATION = "maxDuration";
private static final String PROP_CLASS_NAME = "className";
+ private static final String PROP_CRON = "cron";
private static final String LEGACY_METRIC_ALERT = "COMPOSITE";
private static final String METRIC_ALERT = "METRIC_ALERT";
@@ -129,12 +129,11 @@ public class DetectionConfigValidator implements
ConfigValidator<DetectionConfig
"Missing property ( " + PROP_NAME + " ) in one of the sub-alerts under
" + parentAlertName);
String alertName = MapUtils.getString(detectionYaml, PROP_NAME);
- Preconditions.checkArgument(detectionYaml.containsKey(PROP_TYPE),
- "Missing property ( " + PROP_TYPE + " ) in sub-alert " + alertName);
String alertType = MapUtils.getString(detectionYaml, PROP_TYPE);
-
- Preconditions.checkArgument(SUPPORTED_ALERT_TYPES.contains(alertType),
- "Unsupported type (" + alertType + ") in sub-alert " + alertName);
+ if (alertType != null) {
+ Preconditions.checkArgument(SUPPORTED_ALERT_TYPES.contains(alertType),
+ "Unsupported type (" + alertType + ") in sub-alert " + alertName);
+ }
}
private void validateMetricAlertConfig(Map<String, Object> detectionYaml,
String parentAlertName)
@@ -227,33 +226,31 @@ public class DetectionConfigValidator implements
ConfigValidator<DetectionConfig
}
/**
- * Validate the the detection yaml configuration.
+ * Make sure the config adheres to detection config syntax
*
* @param detectionYaml the detection yaml configuration to be validated
*/
@Override
public void validateYaml(Map<String, Object> detectionYaml) throws
IllegalArgumentException {
- // Validate detectionName
-
Preconditions.checkArgument(detectionYaml.containsKey(PROP_DETECTION_NAME),
"Property missing: " + PROP_DETECTION_NAME);
- String alertName = MapUtils.getString(detectionYaml, PROP_DETECTION_NAME);
+ // detectionName is a required field
+ Preconditions.checkArgument(detectionYaml.containsKey(PROP_DETECTION_NAME),
+ "Property missing: " + PROP_DETECTION_NAME);
// Hack to support 'detectionName' attribute at root level and 'name'
attribute elsewhere
// We consistently use 'name' as a convention to define the sub-alerts.
However, at the root
// level, as a convention, we will use 'detectionName' which defines the
name of the complete alert.
+ String alertName = MapUtils.getString(detectionYaml, PROP_DETECTION_NAME);
detectionYaml.put(PROP_NAME, alertName);
- // By default if 'type' is not specified, we assume it as a METRIC_ALERT
- if (!detectionYaml.containsKey(PROP_TYPE)) {
- detectionYaml.put(PROP_TYPE, METRIC_ALERT);
- }
-
// Validate config depending on the type (METRIC_ALERT OR COMPOSITE_ALERT)
- if (detectionYaml.get(PROP_TYPE).equals(COMPOSITE_ALERT)) {
- validateCompositeAlertConfig(detectionYaml, alertName);
- } else {
- // The legacy type 'COMPOSITE' will be treated as a metric alert along
with the new convention METRIC_ALERT.
- // This is applicable only at the root level to maintain backward
compatibility.
+ if (detectionYaml.get(PROP_TYPE) == null ||
detectionYaml.get(PROP_TYPE).equals(METRIC_ALERT)) {
+ // By default, we treat every alert as a METRIC_ALERT unless explicitly
specified.
+ // Even the legacy type termed 'COMPOSITE' will be treated as a metric
alert along
+ // with the new convention METRIC_ALERT. This is applicable only at the
root level
+ // to maintain backward compatibility.
validateMetricAlertConfig(detectionYaml, alertName);
+ } else {
+ validateCompositeAlertConfig(detectionYaml, alertName);
}
}
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 e953613..d21e5f5 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
@@ -24,10 +24,12 @@ import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.pinot.thirdeye.datalayer.dto.DetectionAlertConfigDTO;
+import org.apache.pinot.thirdeye.datalayer.util.Predicate;
import org.apache.pinot.thirdeye.datasource.DAORegistry;
import org.apache.pinot.thirdeye.detection.ConfigUtils;
import org.quartz.CronExpression;
+import static
org.apache.pinot.thirdeye.detection.alert.scheme.DetectionEmailAlerter.PROP_RECIPIENTS;
import static
org.apache.pinot.thirdeye.detection.yaml.translator.SubscriptionConfigTranslator.*;
@@ -36,21 +38,17 @@ public class SubscriptionConfigValidator implements
ConfigValidator<DetectionAle
private static final String PROP_CLASS_NAME = "className";
/**
- * Perform validation on the alert config like verifying if all the required
fields are set
+ * Perform validation on the parsed & constructed subscription config
*/
@Override
public void validateConfig(DetectionAlertConfigDTO alertConfig) throws
IllegalArgumentException {
Preconditions.checkNotNull(alertConfig);
// Check for all the required fields in the alert
- Preconditions.checkArgument(!StringUtils.isEmpty(alertConfig.getName()),
"Subscription group name field cannot be left empty.");
-
Preconditions.checkArgument(!StringUtils.isEmpty(alertConfig.getApplication()),
"Application field cannot be left empty");
-
- // Empty subscription properties
- Preconditions.checkArgument((alertConfig.getProperties() != null
- && alertConfig.getProperties().get(PROP_CLASS_NAME) != null
- &&
StringUtils.isNotEmpty((alertConfig.getProperties().get(PROP_CLASS_NAME).toString()))),
- "'Type' field cannot be left empty.");
+ Preconditions.checkArgument(!StringUtils.isEmpty(alertConfig.getName()),
+ "Subscription group name field cannot be left empty.");
+
Preconditions.checkArgument(!StringUtils.isEmpty(alertConfig.getApplication()),
+ "Application field cannot be left empty");
// Application name should be valid
Preconditions.checkArgument(!DAORegistry.getInstance().getApplicationDAO().findByName(alertConfig.getApplication()).isEmpty(),
@@ -61,7 +59,13 @@ public class SubscriptionConfigValidator implements
ConfigValidator<DetectionAle
// Cron Validator
Preconditions.checkArgument(CronExpression.isValidExpression(alertConfig.getCronExpression()),
"The subscription cron specified is incorrect. Please verify your cron
expression using online cron"
- + " makers.");
+ + " makers.");
+
+ // Empty subscription properties
+ Preconditions.checkArgument((alertConfig.getProperties() != null
+ && alertConfig.getProperties().get(PROP_CLASS_NAME) != null
+ &&
StringUtils.isNotEmpty((alertConfig.getProperties().get(PROP_CLASS_NAME).toString()))),
+ "'Type' field cannot be left empty.");
// At least one alertScheme is required
Preconditions.checkArgument((alertConfig.getAlertSchemes() != null &&
!alertConfig.getAlertSchemes().isEmpty()),
@@ -74,17 +78,35 @@ public class SubscriptionConfigValidator implements
ConfigValidator<DetectionAle
// detectionConfigIds cannot be empty
List<Long> detectionIds =
ConfigUtils.getLongs(alertConfig.getProperties().get(PROP_DETECTION_CONFIG_IDS));
- Preconditions.checkArgument((detectionIds != null &&
!detectionIds.isEmpty()),
- "A notification group should subscribe to at least one alert. If you
wish to unsubscribe, set active"
- + " to false.");
+ Preconditions.checkArgument(!detectionIds.isEmpty(),
+ "A notification group should subscribe to at least one alert. If you
wish to unsubscribe, set"
+ + " active to false.");
// TODO add more checks like email validity, alert type check, scheme type
check etc.
}
- // Validate the raw subscription yaml configuration
+ /**
+ * Checks to ensure the fields adhere to the syntax
+ */
@Override
public void validateYaml(Map<String, Object> config) throws
IllegalArgumentException {
- // Add validations
+ // Make sure recipients are configured at the right place
+ Preconditions.checkArgument(!config.containsKey(PROP_RECIPIENTS),
+ "Recipients should be configured under the EMAIL alertScheme within
params");
+
+ // Subscription group must subscribe to at least one alert
+ List<String> detectionNames =
ConfigUtils.getList(config.get(PROP_DETECTION_NAMES));
+ Preconditions.checkArgument(!detectionNames.isEmpty(),
+ "A subscription group should subscribe to at least one alert. If you
wish to unsubscribe, set"
+ + " active to false in the subscription config.");
+
+ // Make sure the subscribed detections are valid
+ for (String detectionName : detectionNames) {
+
Preconditions.checkArgument(!DAORegistry.getInstance().getDetectionConfigManager()
+ .findByPredicate(Predicate.EQ("name", detectionName)).isEmpty(),
+ "Cannot find detection " + detectionName + " - Please ensure the
detections listed under "
+ + PROP_DETECTION_NAMES + " exist and are correctly configured.");
+ }
}
/**
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 cd870a7..6d7ae6d 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
@@ -26,6 +26,7 @@ import io.dropwizard.auth.Auth;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
+import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
@@ -261,6 +262,23 @@ public class YamlResource {
return
Response.status(Response.Status.UNAUTHORIZED).entity(responseMessage).build();
}
+ /**
+ * Perform some basic validations on the create alert payload
+ */
+ public void validateCreateAlertYaml(Map<String, String> config) throws
IOException {
+ Preconditions.checkArgument(config.containsKey(PROP_DETECTION), "Detection
pipeline yaml is missing");
+ Preconditions.checkArgument(config.containsKey(PROP_SUBSCRIPTION),
"Subscription group yaml is missing.");
+
+ // check if subscription group has subscribed to the detection
+ Map<String, Object> detectionConfigMap = new
HashMap<>(ConfigUtils.getMap(this.yaml.load(config.get(PROP_DETECTION))));
+ String detectionName = MapUtils.getString(detectionConfigMap,
PROP_DETECTION_NAME);
+ Map<String, Object> subscriptionConfigMap = new
HashMap<>(ConfigUtils.getMap(this.yaml.load(config.get(PROP_SUBSCRIPTION))));
+ List<String> detectionNames =
ConfigUtils.getList(subscriptionConfigMap.get(PROP_DETECTION_NAMES));
+ Preconditions.checkArgument(detectionNames.contains(detectionName),
+ "You have not subscribed to the alert. Please copy-paste the
detectionName under the "
+ + PROP_DETECTION_NAMES + " field in your subscription group.");
+ }
+
@POST
@Path("/create-alert")
@Produces(MediaType.APPLICATION_JSON)
@@ -272,9 +290,19 @@ public class YamlResource {
@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 {
+ // validate the payload
Map<String, String> yamls;
+ try {
+ Preconditions.checkArgument(StringUtils.isNotBlank(payload), "The Yaml
Payload in the request is empty.");
+ yamls = OBJECT_MAPPER.readValue(payload, Map.class);
+ validateCreateAlertYaml(yamls);
+ } catch (IllegalArgumentException e) {
+ return processBadRequestResponse(PROP_DETECTION,
YamlOperations.CREATING.name(), payload, e);
+ } catch (Exception e) {
+ return processServerErrorResponse(PROP_DETECTION,
YamlOperations.CREATING.name(), payload, e);
+ }
- // Detection
+ // Parse and save the detection config
long detectionConfigId;
try {
validatePayload(payload);
@@ -289,7 +317,7 @@ public class YamlResource {
return processServerErrorResponse(PROP_DETECTION,
YamlOperations.CREATING.name(), payload, e);
}
- // Notification
+ // Parse and save the subscription config
long detectionAlertConfigId;
try {
String subscriptionYaml = yamls.get(PROP_SUBSCRIPTION);
diff --git
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/DetectionConfigTranslator.java
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/DetectionConfigTranslator.java
index 91d2fd9..4481c41 100644
---
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/DetectionConfigTranslator.java
+++
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/yaml/translator/DetectionConfigTranslator.java
@@ -288,9 +288,7 @@ public class DetectionConfigTranslator extends
ConfigTranslator<DetectionConfigD
yamlConfigMap.put(PROP_NAME, alertName);
// By default if 'type' is not specified, we assume it as a METRIC_ALERT
- if (!yamlConfigMap.containsKey(PROP_TYPE)) {
- yamlConfigMap.put(PROP_TYPE, METRIC_ALERT);
- }
+ yamlConfigMap.putIfAbsent(PROP_TYPE, METRIC_ALERT);
// Translate config depending on the type (METRIC_ALERT OR COMPOSITE_ALERT)
Map<String, Object> properties;
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 6eabccc..ca0e635 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
@@ -58,6 +58,7 @@ public class SubscriptionConfigTranslator extends
ConfigTranslator<DetectionAler
public static final String PROP_TYPE = "type";
public static final String PROP_CLASS_NAME = "className";
public static final String PROP_PARAM = "params";
+ public static final String DEFAULT_ALERTER_PIPELINE =
"DEFAULT_ALERTER_PIPELINE";
static final String PROP_ALERT_SUPPRESSORS = "alertSuppressors";
static final String PROP_REFERENCE_LINKS = "referenceLinks";
@@ -92,7 +93,7 @@ public class SubscriptionConfigTranslator extends
ConfigTranslator<DetectionAler
Map<String, Object> properties = new HashMap<>();
// Default subscription type is "DEFAULT_ALERTER_PIPELINE"
- alertYamlConfigs.putIfAbsent(PROP_TYPE, "DEFAULT_ALERTER_PIPELINE");
+ alertYamlConfigs.putIfAbsent(PROP_TYPE, DEFAULT_ALERTER_PIPELINE);
for (Map.Entry<String, Object> entry : alertYamlConfigs.entrySet()) {
if (entry.getKey().equals(PROP_TYPE)) {
diff --git
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidatorTest.java
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidatorTest.java
index d6084ac..9539342 100644
---
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidatorTest.java
+++
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/detection/validators/DetectionConfigValidatorTest.java
@@ -199,13 +199,4 @@ public class DetectionConfigValidatorTest {
DetectionConfigValidator detectionConfigValidator = new
DetectionConfigValidator(provider);
detectionConfigValidator.validateYaml(this.yamlConfig2);
}
-
- // type is a compulsory field at sub-alert levels
- @Test(expectedExceptions = IllegalArgumentException.class)
- public void testNoTypeUnderAlertsValidation() {
- ((Map<String, Object>)
ConfigUtils.getList(this.yamlConfig2.get("alerts")).get(0)).remove("type");
-
- DetectionConfigValidator detectionConfigValidator = new
DetectionConfigValidator(provider);
- detectionConfigValidator.validateYaml(this.yamlConfig2);
- }
}
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 0feb1fc..884110f 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
@@ -1,5 +1,7 @@
package org.apache.pinot.thirdeye.detection.yaml;
+import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.pinot.thirdeye.auth.ThirdEyePrincipal;
import org.apache.pinot.thirdeye.dashboard.DetectionPreviewConfiguration;
@@ -67,6 +69,36 @@ public class YamlResourceTest {
}
@Test
+ public void testValidateCreateAlertYaml() throws IOException {
+ // No validation error should be thrown for valid yaml payload
+ String detectionPayload =
IOUtils.toString(this.getClass().getResourceAsStream("detection/detection-config-2.yaml"));
+ String subscriptionPayload =
IOUtils.toString(this.getClass().getResourceAsStream("subscription/subscription-config-5.yaml"));
+ Map<String, String> config = new HashMap<>();
+ config.put("detection", detectionPayload);
+ config.put("subscription", subscriptionPayload);
+ try {
+ this.yamlResource.validateCreateAlertYaml(config);
+ } catch (Exception e) {
+ Assert.fail("No exception should be thrown for valid payload");
+ return;
+ }
+
+ // Throw error if the subscription group is not subscribed to the detection
+ detectionPayload =
IOUtils.toString(this.getClass().getResourceAsStream("detection/detection-config-2.yaml"));
+ subscriptionPayload =
IOUtils.toString(this.getClass().getResourceAsStream("subscription/subscription-config-2.yaml"));
+ config.put("detection", detectionPayload);
+ config.put("subscription", subscriptionPayload);
+ try {
+ this.yamlResource.validateCreateAlertYaml(config);
+ } catch (IllegalArgumentException e) {
+ Assert.assertEquals(e.getMessage(), "You have not subscribed to the
alert. Please copy-paste the"
+ + " detectionName under the subscribedDetections field in your
subscription group.");
+ return;
+ }
+ Assert.fail("Since the subscription group has not subscribed to the alert,
an error should have been thrown.");
+ }
+
+ @Test
public void testCreateOrUpdateDetectionConfig() throws IOException {
String blankYaml = "";
try {
@@ -95,7 +127,7 @@ public class YamlResourceTest {
long id = this.yamlResource.createOrUpdateDetectionConfig(user,
validYaml);
DetectionConfigDTO detection =
daoRegistry.getDetectionConfigManager().findById(id);
Assert.assertNotNull(detection);
- Assert.assertEquals(detection.getName(), "testPipeline");
+ Assert.assertEquals(detection.getName(), "test_detection_1");
} catch (Exception e) {
Assert.fail("Exception should not be thrown for valid yaml. Message: " +
e + " Cause: " + e.getCause(), e);
}
@@ -106,7 +138,7 @@ public class YamlResourceTest {
long id = this.yamlResource.createOrUpdateDetectionConfig(user,
updatedYaml);
DetectionConfigDTO detection =
daoRegistry.getDetectionConfigManager().findById(id);
Assert.assertNotNull(detection);
- Assert.assertEquals(detection.getName(), "testPipeline");
+ Assert.assertEquals(detection.getName(), "test_detection_2");
Assert.assertEquals(detection.getDescription(), "My modified pipeline");
} catch (Exception e) {
Assert.fail("Exception should not be thrown if detection already exists.
Message: " + e + " Cause: " + e.getCause());
@@ -146,7 +178,8 @@ public class YamlResourceTest {
this.yamlResource.createSubscriptionConfig(blankYaml);
Assert.fail("Exception not thrown on empty yaml");
} catch (Exception e) {
- Assert.assertEquals(e.getMessage(), "Subscription group name field
cannot be left empty.");
+ Assert.assertEquals(e.getMessage(), "A subscription group should
subscribe to at least one alert."
+ + " If you wish to unsubscribe, set active to false in the
subscription config.");
}
String inValidYaml = "application:test:application";
@@ -157,7 +190,8 @@ public class YamlResourceTest {
Assert.assertEquals(e.getMessage(), "Could not parse as map:
application:test:application");
}
- String noSubscriptGroupYaml = "application: test_application";
+ // Error should be thrown if subscriptionGroupName is not defined
+ String noSubscriptGroupYaml = "application:
test_application\nsubscribedDetections:\n- test_detection_1\n";
try {
this.yamlResource.createSubscriptionConfig(noSubscriptGroupYaml);
Assert.fail("Exception not thrown on empty yaml");
@@ -240,7 +274,8 @@ public class YamlResourceTest {
this.yamlResource.updateSubscriptionGroup(user, oldId, blankYaml);
Assert.fail("Exception not thrown on empty yaml");
} catch (Exception e) {
- Assert.assertEquals(e.getMessage(), "Subscription group name field
cannot be left empty.");
+ Assert.assertEquals(e.getMessage(), "A subscription group should
subscribe to at least one alert."
+ + " If you wish to unsubscribe, set active to false in the
subscription config.");
}
String inValidYaml = "application:test:application";
@@ -251,7 +286,8 @@ public class YamlResourceTest {
Assert.assertEquals(e.getMessage(), "Could not parse as map:
application:test:application");
}
- String noSubscriptGroupYaml = "application: test_app";
+ // Error should be thrown if no subscriptionGroupName is specified
+ String noSubscriptGroupYaml = "application:
test_app\nsubscribedDetections:\n- test_detection_1";
try {
this.yamlResource.updateSubscriptionGroup(user, oldId,
noSubscriptGroupYaml);
Assert.fail("Exception not thrown on empty yaml");
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-1.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-1.yaml
index 9c19a76..3242f95 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-1.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-1.yaml
@@ -1,4 +1,4 @@
-detectionName: testPipeline
+detectionName: test_detection_1
description: My test pipeline
type: METRIC_ALERT
metric: test_metric
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-2.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-2.yaml
index 1330155..ff899a3 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-2.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/detection/detection-config-2.yaml
@@ -1,4 +1,4 @@
-detectionName: testPipeline
+detectionName: test_detection_2
description: My modified pipeline
type: METRIC_ALERT
metric: test_metric
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-1.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-1.yaml
index 6a16719..bb7de8a 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-1.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-1.yaml
@@ -10,16 +10,17 @@ dimensionRecipients:
- "[email protected]"
dimension: app_name
-fromAddress: [email protected]
-
-recipients:
- to:
- - "[email protected]"
- cc:
- - "[email protected]"
+subscribedDetections:
+- test_detection_1
alertSchemes:
- type: EMAIL
+ params:
+ recipients:
+ to:
+ - "[email protected]"
+ cc:
+ - "[email protected]"
- type: IRIS
params:
plan: thirdye_test_plan
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-2.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-2.yaml
index ef47ca5..4da06f7 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-2.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-2.yaml
@@ -12,16 +12,14 @@ dimensionRecipients:
- "[email protected]"
dimension: app_name
-fromAddress: [email protected]
-
-recipients:
- to:
- - "[email protected]"
- cc:
- - "[email protected]"
-
alertSchemes:
- type: EMAIL
+ params:
+ recipients:
+ to:
+ - "[email protected]"
+ cc:
+ - "[email protected]"
- type: IRIS
params:
plan: thirdye_test_plan
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-3.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-3.yaml
index ca0c621..a479a22 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-3.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-3.yaml
@@ -13,16 +13,14 @@ dimensionRecipients:
- "[email protected]"
dimension: app_name
-fromAddress: [email protected]
-
-recipients:
- to:
- - "[email protected]"
- cc:
- - "[email protected]"
-
alertSchemes:
- type: EMAIL
+ params:
+ recipients:
+ to:
+ - "[email protected]"
+ cc:
+ - "[email protected]"
- type: IRIS
params:
plan: thirdye_test_plan
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-4.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-4.yaml
index 139fe9b..8b0f9bc 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-4.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-4.yaml
@@ -13,16 +13,14 @@ dimensionRecipients:
- "[email protected]"
dimension: app_name
-fromAddress: [email protected]
-
-recipients:
- to:
- - "[email protected]"
- cc:
- - "[email protected]"
-
alertSchemes:
- type: EMAIL
+ params:
+ recipients:
+ to:
+ - "[email protected]"
+ cc:
+ - "[email protected]"
- type: IRIS
params:
plan: thirdye_test_plan
diff --git
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-5.yaml
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-5.yaml
index 9f04929..2863725 100644
---
a/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-5.yaml
+++
b/thirdeye/thirdeye-pinot/src/test/resources/org/apache/pinot/thirdeye/detection/yaml/subscription/subscription-config-5.yaml
@@ -13,19 +13,16 @@ dimensionRecipients:
- "[email protected]"
dimension: app_name
-fromAddress: [email protected]
-
-recipients:
- to:
- - "[email protected]"
- cc:
- - "[email protected]"
-
alertSchemes:
- type: EMAIL
params:
template: ENTITY_GROUPBY_REPORT
subject: METRICS
+ recipients:
+ to:
+ - "[email protected]"
+ cc:
+ - "[email protected]"
- type: IRIS
params:
plan: thirdye_test_plan
diff --git a/thirdeye/thirdeye-pinot/src/test/resources/sample-alert-config.yml
b/thirdeye/thirdeye-pinot/src/test/resources/sample-alert-config.yml
index 9f00a88..3e5d3fe 100644
--- a/thirdeye/thirdeye-pinot/src/test/resources/sample-alert-config.yml
+++ b/thirdeye/thirdeye-pinot/src/test/resources/sample-alert-config.yml
@@ -14,13 +14,13 @@ subscribedDetections:
# or for advanced critical use-cases setup Iris alert by referring to the
documentation
alertSchemes:
- type: EMAIL
-recipients:
- to:
- - "[email protected]" # Specify alert recipient email address here
- - "[email protected]"
- cc:
- - "[email protected]"
-fromAddress: [email protected]
+ params:
+ recipients:
+ to:
+ - "[email protected]" # Specify alert recipient email
address here
+ - "[email protected]"
+ cc:
+ - "[email protected]"
# The below links will appear in the email alerts. This will help alert
recipients to quickly refer and act on.
referenceLinks:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]