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

xhsun 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 367f7e4  [TE] Merge anomaly properties (#4744)
367f7e4 is described below

commit 367f7e4743f00daebb4c67dd9e9c0f31e62b386f
Author: Xiaohui Sun <[email protected]>
AuthorDate: Tue Oct 29 21:04:50 2019 -0700

    [TE] Merge anomaly properties (#4744)
---
 .../app/pods/components/alert-details/component.js | 18 ++++-
 .../thirdeye/detection/algorithm/MergeWrapper.java |  6 +-
 .../wrapper/ChildKeepingMergeWrapper.java          |  4 ++
 .../apache/pinot/thirdeye/util/ThirdEyeUtils.java  | 82 ++++++++++++++++------
 .../pinot/thirdeye/util/ThirdEyeUtilsTest.java     | 20 ++++++
 5 files changed, 104 insertions(+), 26 deletions(-)

diff --git 
a/thirdeye/thirdeye-frontend/app/pods/components/alert-details/component.js 
b/thirdeye/thirdeye-frontend/app/pods/components/alert-details/component.js
index 222a81b..7b3294c 100644
--- a/thirdeye/thirdeye-frontend/app/pods/components/alert-details/component.js
+++ b/thirdeye/thirdeye-frontend/app/pods/components/alert-details/component.js
@@ -1046,9 +1046,25 @@ export default Component.extend({
     return isMetricNew;
   },
 
+  _formattedRule(properties) {
+    let result;
+    if (properties && typeof properties === 'object') {
+      if (properties.detectorComponentName) {
+        // The format is rule1_name:rule1_type,rule2_name:rule2_type ...
+        // For example: 
wow_10_percent_change:PERCENTAGE_RULE,algorithm:ALGORITHM
+        let rules = [];
+        properties.detectorComponentName.split(',').forEach(x => { 
rules.push(x.split(':')[0])});
+        result = rules.sort().join();
+      } else {
+        result = '--';
+      }
+    }
+    return result;
+  },
+
   _fetchAnomalies() {
     set(this, 'getAnomaliesError', false);
-
+    
     // If the user is running the detection with a new metric, we should reset 
the state of time series and anomalies for comparison
     if (this._checkMetricIfCreateAlertPreview()) {
       this.setProperties({
diff --git 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/algorithm/MergeWrapper.java
 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/algorithm/MergeWrapper.java
index f3b6401..f41fe2b 100644
--- 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/algorithm/MergeWrapper.java
+++ 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/algorithm/MergeWrapper.java
@@ -31,7 +31,6 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 import org.apache.commons.collections4.MapUtils;
 import org.apache.pinot.thirdeye.anomaly.AnomalyType;
 import org.apache.pinot.thirdeye.common.dimension.DimensionMap;
@@ -45,6 +44,7 @@ import 
org.apache.pinot.thirdeye.detection.DetectionPipelineResult;
 import org.apache.pinot.thirdeye.detection.DetectionUtils;
 import org.apache.pinot.thirdeye.detection.PredictionResult;
 import org.apache.pinot.thirdeye.detection.spi.model.AnomalySlice;
+import org.apache.pinot.thirdeye.util.ThirdEyeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -204,9 +204,7 @@ public class MergeWrapper extends DetectionPipeline {
         parent.setEndTime(Math.max(parent.getEndTime(), anomaly.getEndTime()));
 
         // merge the anomaly's properties into parent
-        Map<String, String> properties = parent.getProperties();
-        properties.putAll(anomaly.getProperties());
-        parent.setProperties(properties);
+        ThirdEyeUtils.mergeAnomalyProperties(parent.getProperties(), 
anomaly.getProperties());
         if (isExistingAnomaly(parent)) {
           modifiedExistingAnomalies.add(parent);
         } else {
diff --git 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/wrapper/ChildKeepingMergeWrapper.java
 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/wrapper/ChildKeepingMergeWrapper.java
index 1711aeb..e78cba0 100644
--- 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/wrapper/ChildKeepingMergeWrapper.java
+++ 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/detection/wrapper/ChildKeepingMergeWrapper.java
@@ -31,6 +31,7 @@ import 
org.apache.pinot.thirdeye.datalayer.dto.DetectionConfigDTO;
 import org.apache.pinot.thirdeye.datalayer.dto.MergedAnomalyResultDTO;
 import org.apache.pinot.thirdeye.detection.DataProvider;
 import org.apache.pinot.thirdeye.detection.algorithm.MergeWrapper;
+import org.apache.pinot.thirdeye.util.ThirdEyeUtils;
 
 
 /**
@@ -95,6 +96,9 @@ public class ChildKeepingMergeWrapper extends 
BaselineFillingMergeWrapper {
         }
         parent.setEndTime(Math.max(parent.getEndTime(), anomaly.getEndTime()));
 
+        // merge the anomaly's properties into parent
+        ThirdEyeUtils.mergeAnomalyProperties(parent.getProperties(), 
anomaly.getProperties());
+
         if (anomaly.getChildren().isEmpty()) {
           parent.getChildren().add(anomaly);
         } else {
diff --git 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/util/ThirdEyeUtils.java
 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/util/ThirdEyeUtils.java
index 52ff174..ad6bdf3 100644
--- 
a/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/util/ThirdEyeUtils.java
+++ 
b/thirdeye/thirdeye-pinot/src/main/java/org/apache/pinot/thirdeye/util/ThirdEyeUtils.java
@@ -19,6 +19,9 @@
 
 package org.apache.pinot.thirdeye.util;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.base.Preconditions;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
@@ -26,15 +29,10 @@ import com.google.common.cache.LoadingCache;
 import com.google.common.cache.RemovalListener;
 import com.google.common.cache.RemovalNotification;
 import com.google.common.cache.Weigher;
+import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
 import io.dropwizard.configuration.YamlConfigurationFactory;
-import java.util.concurrent.TimeUnit;
-import org.apache.commons.io.FileUtils;
-import org.apache.pinot.common.data.TimeGranularitySpec.TimeFormat;
-import org.apache.pinot.thirdeye.common.dimension.DimensionMap;
-
-import org.apache.pinot.thirdeye.dashboard.ThirdEyeDashboardConfiguration;
-import org.apache.pinot.thirdeye.datalayer.util.DaoProviderUtil;
 import io.dropwizard.jackson.Jackson;
 import java.io.File;
 import java.io.IOException;
@@ -48,37 +46,38 @@ import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
-
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 import javax.validation.Validation;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.pinot.thirdeye.datasource.RelationalQuery;
-import org.apache.pinot.thirdeye.datasource.pinot.resultset.ThirdEyeResultSet;
-import 
org.apache.pinot.thirdeye.datasource.pinot.resultset.ThirdEyeResultSetGroup;
-import org.joda.time.Period;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
+import org.apache.pinot.common.data.TimeGranularitySpec.TimeFormat;
+import org.apache.pinot.thirdeye.common.dimension.DimensionMap;
 import org.apache.pinot.thirdeye.common.time.TimeGranularity;
 import org.apache.pinot.thirdeye.common.time.TimeSpec;
+import org.apache.pinot.thirdeye.dashboard.ThirdEyeDashboardConfiguration;
 import org.apache.pinot.thirdeye.datalayer.bao.MetricConfigManager;
 import org.apache.pinot.thirdeye.datalayer.dto.DatasetConfigDTO;
 import org.apache.pinot.thirdeye.datalayer.dto.MetricConfigDTO;
 import org.apache.pinot.thirdeye.datalayer.pojo.AlertConfigBean.COMPARE_MODE;
-import org.apache.pinot.thirdeye.datalayer.pojo.DatasetConfigBean;
 import org.apache.pinot.thirdeye.datalayer.pojo.MetricConfigBean;
+import org.apache.pinot.thirdeye.datalayer.util.DaoProviderUtil;
 import org.apache.pinot.thirdeye.datasource.DAORegistry;
 import org.apache.pinot.thirdeye.datasource.MetricExpression;
 import org.apache.pinot.thirdeye.datasource.MetricFunction;
+import org.apache.pinot.thirdeye.datasource.RelationalQuery;
 import org.apache.pinot.thirdeye.datasource.ThirdEyeCacheRegistry;
 import org.apache.pinot.thirdeye.datasource.cache.MetricDataset;
+import org.apache.pinot.thirdeye.datasource.pinot.resultset.ThirdEyeResultSet;
+import 
org.apache.pinot.thirdeye.datasource.pinot.resultset.ThirdEyeResultSetGroup;
+import org.joda.time.Period;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.pinot.thirdeye.detection.wrapper.GrouperWrapper.*;
 
 
 public abstract class ThirdEyeUtils {
@@ -619,4 +618,45 @@ public abstract class ThirdEyeUtils {
     }
     return (jvmMaxMemoryInBytes / 102400) * percentage;
   }
+
+
+  /**
+   * Merge child's properties into parent's properties.
+   * If the property exists in both then use parent's property.
+   * For property = "detectorComponentName", combine the parent and child.
+   * @param parent The parent anomaly's properties.
+   * @param child The child anomaly's properties.
+   */
+  public static void mergeAnomalyProperties(Map<String, String> parent, 
Map<String, String> child) {
+    for (String key : child.keySet()) {
+      if (!parent.containsKey(key)) {
+        parent.put(key, child.get(key));
+      } else {
+        // combine detectorComponentName
+        if (key.equals(PROP_DETECTOR_COMPONENT_NAME)) {
+          String component = 
ThirdEyeUtils.combineComponents(parent.get(PROP_DETECTOR_COMPONENT_NAME), 
child.get(PROP_DETECTOR_COMPONENT_NAME));
+          parent.put(PROP_DETECTOR_COMPONENT_NAME, component);
+        }
+      }
+    }
+  }
+
+  /**
+   * Combine two components with comma separated.
+   * For example, will combine "component1" and "component2" into "component1, 
component2".
+   *
+   * @param component1 The first component.
+   * @param component2 The second component.
+   * @return The combined components.
+   */
+  private static String combineComponents(String component1, String 
component2) {
+    List<String> components = new ArrayList<>();
+    for (String component : component1.split(",")) {
+      components.add(component);
+    }
+    for (String component : component2.split(",")) {
+      components.add(component);
+    }
+    return String.join(",", 
components.stream().distinct().collect(Collectors.toList()));
+  }
 }
diff --git 
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/util/ThirdEyeUtilsTest.java
 
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/util/ThirdEyeUtilsTest.java
index 87c9d91..5fc8ab3 100644
--- 
a/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/util/ThirdEyeUtilsTest.java
+++ 
b/thirdeye/thirdeye-pinot/src/test/java/org/apache/pinot/thirdeye/util/ThirdEyeUtilsTest.java
@@ -17,7 +17,9 @@
 package org.apache.pinot.thirdeye.util;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -173,4 +175,22 @@ public class ThirdEyeUtilsTest {
     Assert.assertFalse(errorMessage.contains("e3"));
   }
 
+  @Test
+  public void testMergeAnomalyProperties() {
+    Map<String, String> parentProperties = new HashMap<>();
+    parentProperties.put("p1", "value1");
+    parentProperties.put("p2", "value2");
+    parentProperties.put("detectorComponentName", "rule1");
+
+    Map<String, String> childProperties = new HashMap<>();
+    childProperties.put("p1", "value3");
+    childProperties.put("c1", "value4");
+    childProperties.put("detectorComponentName", "rule2");
+
+    ThirdEyeUtils.mergeAnomalyProperties(parentProperties, childProperties);
+    Assert.assertEquals(parentProperties.get("p1"), "value1");
+    Assert.assertEquals(parentProperties.get("p2"), "value2");
+    Assert.assertEquals(parentProperties.get("c1"), "value4");
+    Assert.assertEquals(parentProperties.get("detectorComponentName"), 
"rule1,rule2");
+  }
 }


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

Reply via email to