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 aea8fca  [TE] anomalies table endpoint (#4501)
aea8fca is described below

commit aea8fca7e2535ce2e8a445754cf5c25bef0cb542
Author: Jihao Zhang <[email protected]>
AuthorDate: Wed Aug 7 10:46:08 2019 -0700

    [TE] anomalies table endpoint (#4501)
    
    Fix the issues of anomalies table endpoint to unblock UI development.
---
 .../dashboard/ThirdEyeDashboardApplication.java    |  2 +
 .../resources/AnomalyFlattenResource.java          | 84 +++++++---------------
 .../resources/TestAnomalyFlattenResource.java      | 39 ++++------
 3 files changed, 42 insertions(+), 83 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 adfd6de..e68606f 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
@@ -38,6 +38,7 @@ import org.apache.pinot.thirdeye.common.ThirdEyeSwaggerBundle;
 import org.apache.pinot.thirdeye.dashboard.configs.AuthConfiguration;
 import org.apache.pinot.thirdeye.dashboard.configs.ResourceConfiguration;
 import org.apache.pinot.thirdeye.dashboard.resources.AdminResource;
+import org.apache.pinot.thirdeye.dashboard.resources.AnomalyFlattenResource;
 import org.apache.pinot.thirdeye.dashboard.resources.AnomalyResource;
 import org.apache.pinot.thirdeye.dashboard.resources.AutoOnboardResource;
 import org.apache.pinot.thirdeye.dashboard.resources.CacheResource;
@@ -181,6 +182,7 @@ public class ThirdEyeDashboardApplication
     env.jersey().register(new ConfigResource(DAO_REGISTRY.getConfigDAO()));
     env.jersey().register(new 
CustomizedEventResource(DAO_REGISTRY.getEventDAO()));
     env.jersey().register(new TimeSeriesResource());
+    env.jersey().register(new 
AnomalyFlattenResource(DAO_REGISTRY.getMergedAnomalyResultDAO()));
     env.jersey().register(new UserDashboardResource(
         DAO_REGISTRY.getMergedAnomalyResultDAO(), 
DAO_REGISTRY.getMetricConfigDAO(), DAO_REGISTRY.getDatasetConfigDAO(),
         DAO_REGISTRY.getDetectionConfigManager(), 
DAO_REGISTRY.getDetectionAlertConfigManager()));
diff --git 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/AnomalyFlattenResource.java
 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/AnomalyFlattenResource.java
index 2238e81..ef48a9e 100644
--- 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/AnomalyFlattenResource.java
+++ 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/dashboard/resources/AnomalyFlattenResource.java
@@ -19,23 +19,22 @@
 
 package org.apache.pinot.thirdeye.dashboard.resources;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import java.io.IOException;
+import io.swagger.annotations.ApiParam;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
-import org.apache.commons.lang3.StringUtils;
+import javax.ws.rs.QueryParam;
 import org.apache.pinot.thirdeye.anomalydetection.context.AnomalyFeedback;
+import org.apache.pinot.thirdeye.api.Constants;
 import org.apache.pinot.thirdeye.common.dimension.DimensionMap;
 import org.apache.pinot.thirdeye.datalayer.bao.MergedAnomalyResultManager;
 import org.apache.pinot.thirdeye.datalayer.dto.MergedAnomalyResultDTO;
-import org.apache.pinot.thirdeye.datasource.DAORegistry;
 
 
 /**
@@ -43,72 +42,39 @@ import org.apache.pinot.thirdeye.datasource.DAORegistry;
  * Convert a list of anomalies to rows of columns so that UI can directly 
convert the anomalies to table
  */
 @Path("thirdeye/table")
+@Api(tags = {Constants.ANOMALY_TAG})
 public class AnomalyFlattenResource {
-  private static final DAORegistry DAO_REGISTRY = DAORegistry.getInstance();
   private MergedAnomalyResultManager mergedAnomalyResultDAO;
-  private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
   public static final String ANOMALY_ID = "anomalyId";
   public static final String ANOMALY_COMMENT = "comment";
-  public static final String FUNCTION_ID = "functionId";
-  public static final String WINDOW_START = "start";
-  public static final String WINDOW_END = "end";
-  private static final String DIMENSION_KEYS  = "keys";
-
-  private static final List<String> REQUIRED_JSON_KEYS 
=Arrays.asList(FUNCTION_ID, WINDOW_START, WINDOW_END);
-  private static final String DEFAULT_DELIMINATOR = ",";
-
-  public AnomalyFlattenResource() {
-    this.mergedAnomalyResultDAO = DAO_REGISTRY.getMergedAnomalyResultDAO();
-  }
 
   public AnomalyFlattenResource(MergedAnomalyResultManager 
mergedAnomalyResultDAO) {
     this.mergedAnomalyResultDAO = mergedAnomalyResultDAO;
   }
 
   /**
-   * Flatten a list of anomaly results to a list of map
-   * @param jsonPayload a json string; the jsonPayload should include keys: 
[functionId, start, end].
-   *                    start and end are in the format of epoch time
-   * @return a list of map
-   * @throws IOException
+   * Returns a list of formatted merged anomalies for UI to render a table
+   * @param detectionConfigId detectionConfigId
+   * @param start start time in epoc milliseconds
+   * @param end end time in epoc milliseconds
+   * @param dimensionKeys a list of keys in dimensions; if null, will return 
all  dimension keys for the anomaly
+   * @return a list of formatted anomalies
    */
   @GET
-  @ApiOperation(value = "View a flatted merged anomalies for collection")
-  public List<Map<String, String>> flatAnomalyResults(String jsonPayload) 
throws IOException {
-    if (StringUtils.isBlank(jsonPayload)) {
-      throw new IllegalArgumentException("jsonPayload cannot be null or 
empty");
-    }
-    Map<String, Object> inputMap = OBJECT_MAPPER.readValue(jsonPayload, 
Map.class);
-
-    // Assert if reuired keys are in the map
-    for (String requiredKey : REQUIRED_JSON_KEYS) {
-      if (!inputMap.containsKey(requiredKey)) {
-        throw new IllegalArgumentException(String.format("Miss %s in input 
json String; %s are required", requiredKey,
-            REQUIRED_JSON_KEYS.toString()));
-      }
-    }
-
+  @ApiOperation(value = "Returns a list of formatted merged anomalies ")
+  public List<Map<String, Object>> flatAnomalyResults(
+      @ApiParam("detection config id") @QueryParam("detectionConfigId") long 
detectionConfigId,
+      @ApiParam("start time for anomalies") @QueryParam("start") long start,
+      @ApiParam("end time for anomalies") @QueryParam("end") long end,
+      @ApiParam("dimension keys") @QueryParam("dimensionKeys") List<String> 
dimensionKeys) {
     // Retrieve anomalies
-    long functionId = Long.valueOf(inputMap.get(FUNCTION_ID).toString());
-    long start = Long.valueOf(inputMap.get(WINDOW_START).toString());
-    long end = Long.valueOf(inputMap.get(WINDOW_END).toString());
     List<MergedAnomalyResultDTO> anomalies = mergedAnomalyResultDAO.
-        findByStartTimeInRangeAndDetectionConfigId(start, end, functionId);
+        findByStartTimeInRangeAndDetectionConfigId(start, end, 
detectionConfigId);
 
     // flatten anomaly result information
-    List<String> tableKeys = null;
-    if (inputMap.containsKey(DIMENSION_KEYS)){
-      Object dimensionKeysObj = inputMap.get(DIMENSION_KEYS);
-      if (dimensionKeysObj instanceof List) {
-        tableKeys = (List<String>) dimensionKeysObj;
-      } else {
-        tableKeys = 
Arrays.asList(dimensionKeysObj.toString().split(DEFAULT_DELIMINATOR));
-      }
-    }
-    List<Map<String, String>> resultList = new ArrayList<>();
+    List<Map<String, Object>> resultList = new ArrayList<>();
     for (MergedAnomalyResultDTO result : anomalies) {
-      resultList.add(flatAnomalyResult(result, tableKeys));
+      resultList.add(flatAnomalyResult(result, dimensionKeys));
     }
     return resultList;
   }
@@ -119,17 +85,17 @@ public class AnomalyFlattenResource {
    * @param tableKeys a list of keys in dimensions; if null, use all keys in 
dimension
    * @return a map of information in the anomaly result with the required keys
    */
-  public static Map<String, String> flatAnomalyResult(MergedAnomalyResultDTO 
anomalyResult,
+  public static Map<String, Object> flatAnomalyResult(MergedAnomalyResultDTO 
anomalyResult,
       List<String> tableKeys) {
     Preconditions.checkNotNull(anomalyResult);
-    Map<String, String> flatMap = new HashMap<>();
-    flatMap.put(ANOMALY_ID, Long.toString(anomalyResult.getId()));
+    Map<String, Object> flatMap = new HashMap<>();
+    flatMap.put(ANOMALY_ID, anomalyResult.getId());
     DimensionMap dimension = anomalyResult.getDimensions();
     if (tableKeys == null) {
       tableKeys = new ArrayList<>(dimension.keySet());
     }
     for (String key : tableKeys) {
-      flatMap.put(key, dimension.containsKey(key)? dimension.get(key) : "");
+      flatMap.put(key, dimension.getOrDefault(key, ""));
     }
     AnomalyFeedback feedback = anomalyResult.getFeedback();
     if (feedback != null) {
@@ -137,7 +103,7 @@ public class AnomalyFlattenResource {
     } else {
       flatMap.put(ANOMALY_COMMENT, "");
     }
-    flatMap.put(anomalyResult.getMetric(), 
Double.toString(anomalyResult.getAvgCurrentVal()));
+    flatMap.put(anomalyResult.getMetric(), anomalyResult.getAvgCurrentVal());
     return flatMap;
   }
 }
diff --git 
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/datasource/resources/TestAnomalyFlattenResource.java
 
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/datasource/resources/TestAnomalyFlattenResource.java
index a0317e2..f501248 100644
--- 
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/datasource/resources/TestAnomalyFlattenResource.java
+++ 
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/datasource/resources/TestAnomalyFlattenResource.java
@@ -19,7 +19,6 @@
 
 package org.apache.pinot.thirdeye.datasource.resources;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -42,7 +41,6 @@ import static 
org.apache.pinot.thirdeye.dashboard.resources.AnomalyFlattenResour
 
 public class TestAnomalyFlattenResource {
   private DAOTestBase testDAOProvider;
-  public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
 
   private DetectionConfigManager detectionConfigDAO;
   private MergedAnomalyResultManager mergedAnomalyResultDAO;
@@ -65,36 +63,29 @@ public class TestAnomalyFlattenResource {
   }
 
   @Test
-  public void testFlatAnomalyResults() throws Exception {
-    Map<String, Object> jsonMap = new HashMap<String, Object>() {
-      {
-        put(FUNCTION_ID, detectionConfigId);
-        put(WINDOW_START, new DateTime(2019, 1, 1, 0, 0).getMillis());
-        put(WINDOW_END, new DateTime(2019, 1, 3, 0, 0).getMillis());
-      }
-    };
-    AnomalyFlattenResource resource = new AnomalyFlattenResource();
-    List<Map<String, String>> actualResults = 
resource.flatAnomalyResults(OBJECT_MAPPER.writeValueAsString(jsonMap));
-    List<Map<String, String>> expectedResults = Arrays.asList(
-        new HashMap<String, String>() {
+  public void testFlatAnomalyResults() {
+    AnomalyFlattenResource resource = new 
AnomalyFlattenResource(this.mergedAnomalyResultDAO);
+    List<Map<String, Object>> actualResults = 
resource.flatAnomalyResults(this.detectionConfigId, new DateTime(2019, 1, 1, 0, 
0).getMillis(), new DateTime(2019, 1, 3, 0, 0).getMillis(), null);
+    List<Map<String, Object>> expectedResults = Arrays.asList(
+        new HashMap<String, Object>() {
           {
-            put(ANOMALY_ID, Long.toString(2));
+            put(ANOMALY_ID, 2L);
             put("what", "a");
             put("where", "b");
             put("when", "c");
             put("how", "d");
-            put("metric", Double.toString(0d));
+            put("metric", 0d);
             put(ANOMALY_COMMENT, "");
           }
         },
-        new HashMap<String, String>() {
+        new HashMap<String, Object>() {
           {
-            put(ANOMALY_ID, Long.toString(3));
+            put(ANOMALY_ID, 3L);
             put("what", "e");
             put("where", "f");
             put("when", "g");
             put("how", "h");
-            put("metric", Double.toString(0d));
+            put("metric", 0d);
             put(ANOMALY_COMMENT, "");
           }
         }
@@ -106,16 +97,16 @@ public class TestAnomalyFlattenResource {
   public void testFlatAnomalyResult() {
     List<MergedAnomalyResultDTO> anomalies = 
TestMergedAnomalyResultManager.mockAnomalies(detectionConfigId);
     MergedAnomalyResultDTO anomaly = anomalies.get(0);
-    anomaly.setId(1l);
-    Map<String, String> actualMap = 
AnomalyFlattenResource.flatAnomalyResult(anomaly, null);
-    Map<String, String> expectMap = new HashMap<String, String>() {
+    anomaly.setId(1L);
+    Map<String, Object> actualMap = 
AnomalyFlattenResource.flatAnomalyResult(anomaly, null);
+    Map<String, Object> expectMap = new HashMap<String, Object>() {
       {
-        put(ANOMALY_ID, Long.toString(anomaly.getId()));
+        put(ANOMALY_ID, anomaly.getId());
         put("what", "a");
         put("where", "b");
         put("when", "c");
         put("how", "d");
-        put("metric", Double.toString(0d));
+        put("metric", 0d);
         put(ANOMALY_COMMENT, "");
       }
     };


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to