This is an automated email from the ASF dual-hosted git repository. jihao pushed a commit to branch alerts-auto-complete in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git
commit c0aab591eeafa0d159055caa84f317f84e1d604b Author: Jihao Zhang <jihzh...@linkedin.com> AuthorDate: Thu May 21 15:05:27 2020 -0700 [TE] endpoints for alerts page filters --- .../dashboard/ThirdEyeDashboardApplication.java | 2 +- .../dashboard/resources/v2/DataResource.java | 98 +++++++++++++++++++--- .../resources/v2/alerts/AlertResource.java | 6 +- .../resources/v2/alerts/AlertSearchFilter.java | 17 +++- .../resources/v2/alerts/AlertSearcher.java | 29 +++++-- .../DetectionConfigurationResource.java | 28 +++++-- .../resources/v2/alerts/AlertSearcherTest.java | 2 +- 7 files changed, 152 insertions(+), 30 deletions(-) diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/ThirdEyeDashboardApplication.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/ThirdEyeDashboardApplication.java index ccd70d3..97e24b5 100644 --- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/ThirdEyeDashboardApplication.java +++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/ThirdEyeDashboardApplication.java @@ -75,7 +75,7 @@ import org.apache.pinot.thirdeye.datasource.loader.DefaultTimeSeriesLoader; import org.apache.pinot.thirdeye.datasource.loader.TimeSeriesLoader; import org.apache.pinot.thirdeye.datasource.sql.resources.SqlDataSourceResource; import org.apache.pinot.thirdeye.detection.DetectionResource; -import org.apache.pinot.thirdeye.detection.annotation.DetectionConfigurationResource; +import org.apache.pinot.thirdeye.detection.DetectionConfigurationResource; import org.apache.pinot.thirdeye.detection.yaml.YamlResource; import org.apache.pinot.thirdeye.detector.email.filter.AlertFilterFactory; import org.apache.pinot.thirdeye.detector.function.AnomalyFunctionFactory; diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/DataResource.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/DataResource.java index 34b8b5a..8b81e66 100644 --- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/DataResource.java +++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/DataResource.java @@ -19,7 +19,10 @@ package org.apache.pinot.thirdeye.dashboard.resources.v2; -import org.apache.pinot.thirdeye.api.Constants; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Strings; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.Multimap; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -36,8 +39,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.TimeUnit; - +import java.util.stream.Collectors; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -45,17 +49,8 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; - import org.apache.commons.lang3.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Strings; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.Multimap; +import org.apache.pinot.thirdeye.api.Constants; import org.apache.pinot.thirdeye.common.time.TimeRange; import org.apache.pinot.thirdeye.dashboard.Utils; import org.apache.pinot.thirdeye.dashboard.views.heatmap.HeatMapViewHandler; @@ -63,13 +58,23 @@ import org.apache.pinot.thirdeye.dashboard.views.heatmap.HeatMapViewRequest; import org.apache.pinot.thirdeye.dashboard.views.heatmap.HeatMapViewResponse; import org.apache.pinot.thirdeye.datalayer.bao.AlertConfigManager; import org.apache.pinot.thirdeye.datalayer.bao.AnomalyFunctionManager; +import org.apache.pinot.thirdeye.datalayer.bao.ApplicationManager; import org.apache.pinot.thirdeye.datalayer.bao.DatasetConfigManager; +import org.apache.pinot.thirdeye.datalayer.bao.DetectionAlertConfigManager; +import org.apache.pinot.thirdeye.datalayer.bao.DetectionConfigManager; import org.apache.pinot.thirdeye.datalayer.bao.MetricConfigManager; import org.apache.pinot.thirdeye.datalayer.dto.AlertConfigDTO; import org.apache.pinot.thirdeye.datalayer.dto.AnomalyFunctionDTO; +import org.apache.pinot.thirdeye.datalayer.dto.ApplicationDTO; import org.apache.pinot.thirdeye.datalayer.dto.DatasetConfigDTO; +import org.apache.pinot.thirdeye.datalayer.dto.DetectionAlertConfigDTO; +import org.apache.pinot.thirdeye.datalayer.dto.DetectionConfigDTO; import org.apache.pinot.thirdeye.datalayer.dto.MergedAnomalyResultDTO; import org.apache.pinot.thirdeye.datalayer.dto.MetricConfigDTO; +import org.apache.pinot.thirdeye.datalayer.pojo.ApplicationBean; +import org.apache.pinot.thirdeye.datalayer.pojo.DetectionAlertConfigBean; +import org.apache.pinot.thirdeye.datalayer.pojo.DetectionConfigBean; +import org.apache.pinot.thirdeye.datalayer.util.Predicate; import org.apache.pinot.thirdeye.datasource.DAORegistry; import org.apache.pinot.thirdeye.datasource.MetricExpression; import org.apache.pinot.thirdeye.datasource.ThirdEyeCacheRegistry; @@ -77,6 +82,11 @@ import org.apache.pinot.thirdeye.datasource.cache.QueryCache; import org.apache.pinot.thirdeye.detector.email.filter.AlertFilterFactory; import org.apache.pinot.thirdeye.detector.function.AnomalyFunctionFactory; import org.apache.pinot.thirdeye.util.ThirdEyeUtils; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Do's and Dont's @@ -103,6 +113,9 @@ public class DataResource { private final DatasetConfigManager datasetConfigDAO; private final AnomalyFunctionManager anomalyFunctionDAO; private final AlertConfigManager alertConfigDAO; + private final DetectionConfigManager detectionConfigDAO; + private final DetectionAlertConfigManager detectionAlertConfigDAO; + private final ApplicationManager applicationManager; private final LoadingCache<String, Long> collectionMaxDataTimeCache; private final LoadingCache<String, String> dimensionsFilterCache; @@ -114,6 +127,9 @@ public class DataResource { this.datasetConfigDAO = DAO_REGISTRY.getDatasetConfigDAO(); this.anomalyFunctionDAO = DAO_REGISTRY.getAnomalyFunctionDAO(); this.alertConfigDAO = DAO_REGISTRY.getAlertConfigDAO(); + this.detectionConfigDAO = DAO_REGISTRY.getDetectionConfigManager(); + this.detectionAlertConfigDAO = DAO_REGISTRY.getDetectionAlertConfigManager(); + this.applicationManager = DAO_REGISTRY.getApplicationDAO(); this.queryCache = CACHE_REGISTRY_INSTANCE.getQueryCache(); this.collectionMaxDataTimeCache = CACHE_REGISTRY_INSTANCE.getDatasetMaxDataTimeCache(); @@ -194,6 +210,64 @@ public class DataResource { } /** + * Gets detection configs where name like. + * + * @param name the name + * @return the detections where name like + */ + @GET + @Path("autocomplete/detection") + public List<DetectionConfigDTO> getDetectionsWhereNameLike(@ApiParam("detection name") @QueryParam("name") String name) { + List<DetectionConfigDTO> result = this.detectionConfigDAO.findByPredicate(Predicate.LIKE("name", "%" + name.trim() + "%")); + result.sort(Comparator.comparing(DetectionConfigBean::getName)); + return result; + } + + /** + * Gets subscription groups where name like. + * + * @param name the name + * @return the subscription where name like + */ + @GET + @Path("autocomplete/subscription") + public List<DetectionAlertConfigDTO> getSubscriptionWhereNameLike(@QueryParam("name") String name) { + List<DetectionAlertConfigDTO> result = this.detectionAlertConfigDAO.findByPredicate(Predicate.LIKE("name", "%" + name.trim() + "%")); + result.sort(Comparator.comparing(DetectionAlertConfigBean::getName)); + return result; + } + + /** + * Gets applications where name like. + * + * @param name the name + * @return the applications where name like + */ + @GET + @Path("autocomplete/application") + public List<ApplicationDTO> getApplicationsWhereNameLike(@QueryParam("name") String name) { + List<ApplicationDTO> result = this.applicationManager.findByPredicate(Predicate.LIKE("application", "%" + name.trim() + "%")); + result.sort(Comparator.comparing(ApplicationBean::getApplication)); + return result; + } + + /** + * Gets detection config creators where name like. + * + * @param name the name + * @return the created bys where name like + */ + @GET + @Path("autocomplete/detection-createdby") + public Set<String> getCreatedBysWhereNameLike(@QueryParam("name") String name) { + List<DetectionConfigDTO> result = this.detectionConfigDAO.findByPredicate(Predicate.LIKE("createdBy", "%" + name.trim() + "%")); + return result.stream() + .map(DetectionConfigBean::getCreatedBy) + .sorted() + .collect(Collectors.toCollection(TreeSet::new)); + } + + /** * Returns list of Anomaly functions matching given name * @param name * @return diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertResource.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertResource.java index 1bc4f93..e7395b0e 100644 --- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertResource.java +++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertResource.java @@ -58,6 +58,7 @@ public class AlertResource { * @param subscriptionGroups the subscription groups for the alerts * @param names the names for the alerts * @param createdBy the owners for the alerts + * @param subscribedBy the subscriber for the alerts * @param ruleTypes the rule types for the alerts * @param metrics the metrics for the alerts * @param datasets the datasets for the alerts @@ -70,10 +71,11 @@ public class AlertResource { public Response findAlerts(@QueryParam("limit") @DefaultValue("10") long limit, @QueryParam("offset") @DefaultValue("0") long offset, @QueryParam("application") List<String> applications, @QueryParam("subscriptionGroup") List<String> subscriptionGroups, @QueryParam("names") List<String> names, - @QueryParam("createdBy") List<String> createdBy, @QueryParam("ruleType") List<String> ruleTypes, + @QueryParam("createdBy") List<String> createdBy, @QueryParam("subscribedBy") List<String> subscribedBy, @QueryParam("ruleType") List<String> ruleTypes, @QueryParam("metric") List<String> metrics, @QueryParam("dataset") List<String> datasets, @QueryParam("active") Boolean active) { - AlertSearchFilter searchFilter = new AlertSearchFilter(applications, subscriptionGroups, names, createdBy, ruleTypes, metrics, datasets, active); + AlertSearchFilter searchFilter = + new AlertSearchFilter(applications, subscriptionGroups, names, createdBy, subscribedBy, ruleTypes, metrics, datasets, active); return Response.ok().entity(this.alertSearcher.search(searchFilter, limit, offset)).build(); } } diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearchFilter.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearchFilter.java index 0c488ff..52bb3ee 100644 --- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearchFilter.java +++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearchFilter.java @@ -31,6 +31,7 @@ public class AlertSearchFilter { private final List<String> applications; private final List<String> subscriptionGroups; private final List<String> createdBy; + private final List<String> subscribedBy; private final List<String> ruleTypes; private final List<String> metrics; private final List<String> datasets; @@ -41,6 +42,7 @@ public class AlertSearchFilter { this.applications = Collections.emptyList(); this.subscriptionGroups = Collections.emptyList(); this.createdBy = Collections.emptyList(); + this.subscribedBy = Collections.emptyList(); this.ruleTypes = Collections.emptyList(); this.datasets = Collections.emptyList(); this.metrics = Collections.emptyList(); @@ -55,17 +57,19 @@ public class AlertSearchFilter { * @param subscriptionGroups the subscription groups * @param names the names * @param createdBy the createdBy + * @param subscribedBy the subscribed by * @param ruleTypes the rule types * @param metrics the metrics * @param datasets the datasets * @param active the active */ public AlertSearchFilter(List<String> applications, List<String> subscriptionGroups, List<String> names, - List<String> createdBy, List<String> ruleTypes, List<String> metrics, List<String> datasets, Boolean active) { + List<String> createdBy, List<String> subscribedBy, List<String> ruleTypes, List<String> metrics, List<String> datasets, Boolean active) { this.applications = applications; this.subscriptionGroups = subscriptionGroups; this.names = names; this.createdBy = createdBy; + this.subscribedBy = subscribedBy; this.ruleTypes = ruleTypes; this.metrics = metrics; this.datasets = datasets; @@ -100,6 +104,15 @@ public class AlertSearchFilter { } /** + * Gets subscribedBy. + * + * @return the subscribedBy + */ + public List<String> getSubscribedBy() { + return subscribedBy; + } + + /** * Gets rule types. * * @return the rule types @@ -151,7 +164,7 @@ public class AlertSearchFilter { */ public boolean isEmpty() { return this.applications.isEmpty() && this.subscriptionGroups.isEmpty() && this.names.isEmpty() - && this.createdBy.isEmpty() && this.ruleTypes.isEmpty() && this.metrics.isEmpty() && this.datasets.isEmpty() + && this.createdBy.isEmpty() && this.subscribedBy.isEmpty() && this.ruleTypes.isEmpty() && this.metrics.isEmpty() && this.datasets.isEmpty() && active == null; } } diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcher.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcher.java index 78fe3a1..c5aec8c 100644 --- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcher.java +++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcher.java @@ -24,6 +24,7 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Multimap; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -116,7 +117,12 @@ public class AlertSearcher { private List<DetectionAlertConfigDTO> findRelatedSubscriptionGroups(AlertSearchQuery searchQuery) { AlertSearchFilter searchFilter = searchQuery.searchFilter; + if (searchFilter.getApplications().isEmpty() && searchFilter.getSubscriptionGroups().isEmpty() + && searchFilter.getSubscribedBy().isEmpty()) { + return this.detectionAlertConfigDAO.findAll(); + } List<Predicate> predicates = new ArrayList<>(); + Set<DetectionAlertConfigDTO> subscriptionGroups = new HashSet<>(); if (!searchFilter.getApplications().isEmpty()) { predicates.add(Predicate.IN("application", searchFilter.getApplications().toArray())); } @@ -124,10 +130,23 @@ public class AlertSearcher { predicates.add(Predicate.IN("name", searchFilter.getSubscriptionGroups().toArray())); } if (!predicates.isEmpty()) { - return this.detectionAlertConfigDAO.findByPredicate(Predicate.AND(predicates.toArray(new Predicate[0]))); - } else { - return this.detectionAlertConfigDAO.findAll(); + subscriptionGroups.addAll( + this.detectionAlertConfigDAO.findByPredicate(Predicate.AND(predicates.toArray(new Predicate[0])))); + } + if (!searchFilter.getSubscribedBy().isEmpty()) { + List<DetectionAlertConfigDTO> jsonValResult = this.detectionAlertConfigDAO.findByPredicateJsonVal(Predicate.OR( + searchFilter.getSubscribedBy() + .stream() + .map(name -> Predicate.LIKE("jsonVal", "%recipients%" + name + "%")) + .toArray(Predicate[]::new))); + if (predicates.isEmpty()) { + subscriptionGroups.addAll(jsonValResult); + } else { + // intersect the result from both tables + subscriptionGroups = jsonValResult.stream().filter(subscriptionGroups::contains).collect(Collectors.toSet()); + } } + return new ArrayList<>(subscriptionGroups); } private List<DetectionConfigDTO> findDetectionConfig(AlertSearchQuery searchQuery, @@ -141,7 +160,7 @@ public class AlertSearcher { // look up and run the search filters on the detection config index List<DetectionConfigDTO> indexedResult = new ArrayList<>(); List<Predicate> indexPredicates = new ArrayList<>(); - if (!searchFilter.getApplications().isEmpty() || !searchFilter.getSubscriptionGroups().isEmpty()) { + if (!searchFilter.getApplications().isEmpty() || !searchFilter.getSubscriptionGroups().isEmpty() || !searchFilter.getSubscribedBy().isEmpty()) { Set<Long> detectionConfigIds = new TreeSet<>(); for (DetectionAlertConfigDTO subscriptionGroup : subscriptionGroups) { detectionConfigIds.addAll(subscriptionGroup.getVectorClocks().keySet()); @@ -208,7 +227,7 @@ public class AlertSearcher { jsonValResult.addAll(indexedResult); result = jsonValResult; } - return result; + return result.stream().sorted(Comparator.comparingLong(AbstractDTO::getId).reversed()).collect(Collectors.toList()); } /** diff --git a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/annotation/DetectionConfigurationResource.java b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionConfigurationResource.java similarity index 58% rename from thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/annotation/DetectionConfigurationResource.java rename to thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionConfigurationResource.java index 65befe3..8c99190 100644 --- a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/annotation/DetectionConfigurationResource.java +++ b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/DetectionConfigurationResource.java @@ -15,27 +15,41 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. + * */ -package org.apache.pinot.thirdeye.detection.annotation; +package org.apache.pinot.thirdeye.detection; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.pinot.thirdeye.detection.annotation.registry.DetectionRegistry; +import io.swagger.annotations.Api; import io.swagger.annotations.ApiParam; +import java.util.List; +import java.util.stream.Collectors; import javax.ws.rs.GET; import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Response; +import org.apache.pinot.thirdeye.api.Constants; +import org.apache.pinot.thirdeye.detection.annotation.Components; +import org.apache.pinot.thirdeye.detection.annotation.registry.DetectionRegistry; -@Path("/detection/annotation") +@Path("/detection/rule") +@Api(tags = {Constants.DETECTION_TAG}) public class DetectionConfigurationResource { private static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static DetectionRegistry detectionRegistry = DetectionRegistry.getInstance(); + private static String TUNABLE_TYPE = "TUNABLE"; + private static String BASELINE_TYPE = "BASELINE"; + @GET - public Response getConfigurations(@ApiParam("tag") String tag) throws Exception { - return Response.ok( - OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(detectionRegistry.getAllAnnotation())) - .build(); + public Response getRules() throws Exception { + List<Components> componentsList = detectionRegistry.getAllAnnotation(); + componentsList = componentsList.stream().filter(component -> { + String type = component.type().toUpperCase(); + return !type.contains(TUNABLE_TYPE) && !type.contains(BASELINE_TYPE); + }).collect(Collectors.toList()); + return Response.ok(OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(componentsList)).build(); } } diff --git a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcherTest.java b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcherTest.java index 3e25461..eee5bfa 100644 --- a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcherTest.java +++ b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/dashboard/resources/v2/alerts/AlertSearcherTest.java @@ -67,7 +67,7 @@ public class AlertSearcherTest { @Test public void testSearchActive() { AlertSearcher searcher = new AlertSearcher(); - Map<String, Object> result = searcher.search(new AlertSearchFilter(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), true), 10 ,0); + Map<String, Object> result = searcher.search(new AlertSearchFilter(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), true), 10 ,0); Assert.assertEquals(result.get("count"), 1L); Assert.assertEquals(result.get("limit"), 10L); Assert.assertEquals(result.get("offset"), 0L); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org For additional commands, e-mail: commits-h...@pinot.apache.org