@Test public void testValidateCreateAlertYaml() throws IOException { 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; } 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 (ConfigValidationException e) { Assert.assertEquals(e.getMessage(), "You have not subscribed to the alert. Please configure 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."); }
public void validateCreateAlertYaml(Map<String, String> config) throws ConfigValidationException { ConfigValidationUtils.checkArgument(config.containsKey(PROP_DETECTION), String.format(MISSING_YAML_MSG, "Detection")); ConfigValidationUtils.checkArgument(config.containsKey(PROP_SUBSCRIPTION), String.format(MISSING_YAML_MSG, "Subscription Group")); Map<String, Object> detectionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_DETECTION))); String detectionName = MapUtils.getString(detectionConfigMap, PROP_DETECTION_NAME); Map<String, Object> subscriptionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_SUBSCRIPTION))); List<String> detectionNames = ConfigUtils.getList(subscriptionConfigMap.get(PROP_DETECTION_NAMES)); ConfigValidationUtils.checkArgument(detectionNames.contains(detectionName), "You have not subscribed to the alert. Please configure the detectionName under the " + PROP_DETECTION_NAMES + " field in your subscription group."); }
YamlResource { public void validateCreateAlertYaml(Map<String, String> config) throws ConfigValidationException { ConfigValidationUtils.checkArgument(config.containsKey(PROP_DETECTION), String.format(MISSING_YAML_MSG, "Detection")); ConfigValidationUtils.checkArgument(config.containsKey(PROP_SUBSCRIPTION), String.format(MISSING_YAML_MSG, "Subscription Group")); Map<String, Object> detectionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_DETECTION))); String detectionName = MapUtils.getString(detectionConfigMap, PROP_DETECTION_NAME); Map<String, Object> subscriptionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_SUBSCRIPTION))); List<String> detectionNames = ConfigUtils.getList(subscriptionConfigMap.get(PROP_DETECTION_NAMES)); ConfigValidationUtils.checkArgument(detectionNames.contains(detectionName), "You have not subscribed to the alert. Please configure the detectionName under the " + PROP_DETECTION_NAMES + " field in your subscription group."); } }
YamlResource { public void validateCreateAlertYaml(Map<String, String> config) throws ConfigValidationException { ConfigValidationUtils.checkArgument(config.containsKey(PROP_DETECTION), String.format(MISSING_YAML_MSG, "Detection")); ConfigValidationUtils.checkArgument(config.containsKey(PROP_SUBSCRIPTION), String.format(MISSING_YAML_MSG, "Subscription Group")); Map<String, Object> detectionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_DETECTION))); String detectionName = MapUtils.getString(detectionConfigMap, PROP_DETECTION_NAME); Map<String, Object> subscriptionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_SUBSCRIPTION))); List<String> detectionNames = ConfigUtils.getList(subscriptionConfigMap.get(PROP_DETECTION_NAMES)); ConfigValidationUtils.checkArgument(detectionNames.contains(detectionName), "You have not subscribed to the alert. Please configure the detectionName under the " + PROP_DETECTION_NAMES + " field in your subscription group."); } YamlResource(Map<String, Map<String, Object>> alerterConfig, DetectionPreviewConfiguration previewConfig,
      double alertOnboardingPermitPerSecond);  YamlResource(Map<String, Map<String, Object>> alerterConfig, DetectionPreviewConfiguration previewConfig); }
YamlResource { public void validateCreateAlertYaml(Map<String, String> config) throws ConfigValidationException { ConfigValidationUtils.checkArgument(config.containsKey(PROP_DETECTION), String.format(MISSING_YAML_MSG, "Detection")); ConfigValidationUtils.checkArgument(config.containsKey(PROP_SUBSCRIPTION), String.format(MISSING_YAML_MSG, "Subscription Group")); Map<String, Object> detectionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_DETECTION))); String detectionName = MapUtils.getString(detectionConfigMap, PROP_DETECTION_NAME); Map<String, Object> subscriptionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_SUBSCRIPTION))); List<String> detectionNames = ConfigUtils.getList(subscriptionConfigMap.get(PROP_DETECTION_NAMES)); ConfigValidationUtils.checkArgument(detectionNames.contains(detectionName), "You have not subscribed to the alert. Please configure the detectionName under the " + PROP_DETECTION_NAMES + " field in your subscription group."); } YamlResource(Map<String, Map<String, Object>> alerterConfig, DetectionPreviewConfiguration previewConfig,
      double alertOnboardingPermitPerSecond);  YamlResource(Map<String, Map<String, Object>> alerterConfig, DetectionPreviewConfiguration previewConfig); void validateCreateAlertYaml(Map<String, String> config); @POST @Path("/create-alert") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @PermitAll @ApiOperation("Use yaml to create both subscription and detection yaml. ") Response createYamlAlert(
      @Auth ThirdEyePrincipal user,
      @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 tuningStartTime,
      @ApiParam("tuning window end time for tunable components") @QueryParam("endTime") long tuningEndTime); @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Set up a detection pipeline using a YAML config") Response createDetectionPipelineApi(
      @ApiParam("yaml config") 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); @PUT @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Edit a detection pipeline using a YAML config") Response updateDetectionPipelineApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("yaml config") String payload,
      @ApiParam("the detection config id to edit") @PathParam("id") long id,
      @ApiParam("tuning window start time for tunable components")  @QueryParam("startTime") long startTime,
      @ApiParam("tuning window end time for tunable components") @QueryParam("endTime") long endTime); @POST @Path("/create-or-update") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Create a new detection config or update existing if one already exists") Response createOrUpdateDetectionConfigApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("yaml config") String payload); @POST @Path("/subscription/create-or-update") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Create a new subscription config or update existing if one already exists") Response createOrUpdateSubscriptionConfigApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("yaml config") String payload); long createSubscriptionConfig(@NotNull String payload); @POST @Path("/subscription") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Create a subscription group using a YAML config") @SuppressWarnings("unchecked") Response createSubscriptionConfigApi(
      @ApiParam("payload") String payload); @PUT @Path("/subscription/{id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Edit a subscription group using a YAML config") Response updateSubscriptionGroupApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("payload") String payload,
      @ApiParam("the detection alert config id to edit") @PathParam("id") long id); @POST @Path("/preview") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Preview the anomaly detection result of a YAML configuration") Response yamlPreviewApi(
      @QueryParam("start") long start,
      @QueryParam("end") long end,
      @QueryParam("tuningStart") long tuningStart,
      @QueryParam("tuningEnd") long tuningEnd,
      @ApiParam("jsonPayload") String payload); @POST @Path("/preview/{id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Preview the anomaly detection result of a YAML configuration, with an existing config and historical anomalies") Response yamlPreviewWithHistoricalAnomalies(
      @PathParam("id") long id,
      @QueryParam("start") long start,
      @QueryParam("end") long end,
      @QueryParam("tuningStart") long tuningStart,
      @QueryParam("tuningEnd") long tuningEnd,
      @ApiParam("jsonPayload") String payload); @POST @Path("/preview/baseline") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Get baseline from YAML configuration") /* TODO: Will return baseline from yamlPreviewApi together with detection in the future. */ Response yamlPreviewBaselineApi(
      @QueryParam("start") long start,
      @QueryParam("end") long end,
      @QueryParam("urn") @NotNull String urn,
      @QueryParam("tuningStart") long tuningStart,
      @QueryParam("tuningEnd") long tuningEnd,
      @ApiParam("jsonPayload") @NotNull String payload,
      @QueryParam("ruleName") String ruleName); @PUT @Path("/activation/{id}") @ApiOperation("Make detection active or inactive, given id") @Produces(MediaType.APPLICATION_JSON) Response toggleActivation(
      @ApiParam("Detection configuration id for the alert") @NotNull @PathParam("id") long detectionId,
      @ApiParam("Active status you want to set for the alert") @NotNull @QueryParam("active") boolean active); @GET @Path("/list") @ApiOperation( "Get the list of all detection YAML configurations as JSON enhanced with additional information, optionally filtered." + "IMPORTANT NOTE: This endpoint is deprecated because it is not scalable. Please use the /alerts endpoint instead. " + "For now, it is limited to list and filter the most recent 100 alerts only. ") @Produces(MediaType.APPLICATION_JSON) @Deprecated Response listYamls(
      @ApiParam("Dataset the detection configurations should be filtered by") @QueryParam("dataset") String dataset,
      @ApiParam("Metric the detection configurations should be filtered by") @QueryParam("metric") String metric); @PUT @Path("/notify/{id}") @ApiOperation("Send notification email for detection alert config") Response triggerNotification(
      @ApiParam("Subscription configuration id for the alert") @NotNull @PathParam("id") long subscriptionId); }
YamlResource { public void validateCreateAlertYaml(Map<String, String> config) throws ConfigValidationException { ConfigValidationUtils.checkArgument(config.containsKey(PROP_DETECTION), String.format(MISSING_YAML_MSG, "Detection")); ConfigValidationUtils.checkArgument(config.containsKey(PROP_SUBSCRIPTION), String.format(MISSING_YAML_MSG, "Subscription Group")); Map<String, Object> detectionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_DETECTION))); String detectionName = MapUtils.getString(detectionConfigMap, PROP_DETECTION_NAME); Map<String, Object> subscriptionConfigMap = ConfigUtils.getMap(this.yaml.load(config.get(PROP_SUBSCRIPTION))); List<String> detectionNames = ConfigUtils.getList(subscriptionConfigMap.get(PROP_DETECTION_NAMES)); ConfigValidationUtils.checkArgument(detectionNames.contains(detectionName), "You have not subscribed to the alert. Please configure the detectionName under the " + PROP_DETECTION_NAMES + " field in your subscription group."); } YamlResource(Map<String, Map<String, Object>> alerterConfig, DetectionPreviewConfiguration previewConfig,
      double alertOnboardingPermitPerSecond);  YamlResource(Map<String, Map<String, Object>> alerterConfig, DetectionPreviewConfiguration previewConfig); void validateCreateAlertYaml(Map<String, String> config); @POST @Path("/create-alert") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @PermitAll @ApiOperation("Use yaml to create both subscription and detection yaml. ") Response createYamlAlert(
      @Auth ThirdEyePrincipal user,
      @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 tuningStartTime,
      @ApiParam("tuning window end time for tunable components") @QueryParam("endTime") long tuningEndTime); @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Set up a detection pipeline using a YAML config") Response createDetectionPipelineApi(
      @ApiParam("yaml config") 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); @PUT @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Edit a detection pipeline using a YAML config") Response updateDetectionPipelineApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("yaml config") String payload,
      @ApiParam("the detection config id to edit") @PathParam("id") long id,
      @ApiParam("tuning window start time for tunable components")  @QueryParam("startTime") long startTime,
      @ApiParam("tuning window end time for tunable components") @QueryParam("endTime") long endTime); @POST @Path("/create-or-update") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Create a new detection config or update existing if one already exists") Response createOrUpdateDetectionConfigApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("yaml config") String payload); @POST @Path("/subscription/create-or-update") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Create a new subscription config or update existing if one already exists") Response createOrUpdateSubscriptionConfigApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("yaml config") String payload); long createSubscriptionConfig(@NotNull String payload); @POST @Path("/subscription") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Create a subscription group using a YAML config") @SuppressWarnings("unchecked") Response createSubscriptionConfigApi(
      @ApiParam("payload") String payload); @PUT @Path("/subscription/{id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @PermitAll @ApiOperation("Edit a subscription group using a YAML config") Response updateSubscriptionGroupApi(
      @Auth ThirdEyePrincipal user,
      @ApiParam("payload") String payload,
      @ApiParam("the detection alert config id to edit") @PathParam("id") long id); @POST @Path("/preview") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Preview the anomaly detection result of a YAML configuration") Response yamlPreviewApi(
      @QueryParam("start") long start,
      @QueryParam("end") long end,
      @QueryParam("tuningStart") long tuningStart,
      @QueryParam("tuningEnd") long tuningEnd,
      @ApiParam("jsonPayload") String payload); @POST @Path("/preview/{id}") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Preview the anomaly detection result of a YAML configuration, with an existing config and historical anomalies") Response yamlPreviewWithHistoricalAnomalies(
      @PathParam("id") long id,
      @QueryParam("start") long start,
      @QueryParam("end") long end,
      @QueryParam("tuningStart") long tuningStart,
      @QueryParam("tuningEnd") long tuningEnd,
      @ApiParam("jsonPayload") String payload); @POST @Path("/preview/baseline") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.TEXT_PLAIN) @ApiOperation("Get baseline from YAML configuration") /* TODO: Will return baseline from yamlPreviewApi together with detection in the future. */ Response yamlPreviewBaselineApi(
      @QueryParam("start") long start,
      @QueryParam("end") long end,
      @QueryParam("urn") @NotNull String urn,
      @QueryParam("tuningStart") long tuningStart,
      @QueryParam("tuningEnd") long tuningEnd,
      @ApiParam("jsonPayload") @NotNull String payload,
      @QueryParam("ruleName") String ruleName); @PUT @Path("/activation/{id}") @ApiOperation("Make detection active or inactive, given id") @Produces(MediaType.APPLICATION_JSON) Response toggleActivation(
      @ApiParam("Detection configuration id for the alert") @NotNull @PathParam("id") long detectionId,
      @ApiParam("Active status you want to set for the alert") @NotNull @QueryParam("active") boolean active); @GET @Path("/list") @ApiOperation( "Get the list of all detection YAML configurations as JSON enhanced with additional information, optionally filtered." + "IMPORTANT NOTE: This endpoint is deprecated because it is not scalable. Please use the /alerts endpoint instead. " + "For now, it is limited to list and filter the most recent 100 alerts only. ") @Produces(MediaType.APPLICATION_JSON) @Deprecated Response listYamls(
      @ApiParam("Dataset the detection configurations should be filtered by") @QueryParam("dataset") String dataset,
      @ApiParam("Metric the detection configurations should be filtered by") @QueryParam("metric") String metric); @PUT @Path("/notify/{id}") @ApiOperation("Send notification email for detection alert config") Response triggerNotification(
      @ApiParam("Subscription configuration id for the alert") @NotNull @PathParam("id") long subscriptionId);  }