You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by wu...@apache.org on 2018/06/05 07:29:45 UTC

[incubator-servicecomb-java-chassis] 03/06: [SCB-616] add AccessLogItemMeta compare logic

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

wujimin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 62647a9b77113ae6e0569cc1b69127a1acd6851e
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Sun May 27 15:11:13 2018 +0800

    [SCB-616] add AccessLogItemMeta compare logic
---
 .../impl/VertxRestAccessLogPatternParser.java      |  86 +++++++++++++++-
 .../impl/VertxRestAccessLogPatternParserTest.java  | 110 ++++++++++++++++++++-
 2 files changed, 192 insertions(+), 4 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
index 666d9a9..5295f10 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParser.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.List;
 
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
@@ -31,11 +32,30 @@ import io.vertx.ext.web.RoutingContext;
  * The parser is used for rest-over-vertx transport.
  */
 public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<RoutingContext> {
+  public static final Comparator<AccessLogItemMetaWrapper> accessLogItemMetaWrapperComparator = (w1, w2) -> {
+    AccessLogItemMeta meta1 = w1.getAccessLogItemMeta();
+    AccessLogItemMeta meta2 = w2.getAccessLogItemMeta();
+    int result = meta1.getOrder() - meta2.getOrder();
+    if (result != 0) {
+      return result;
+    }
+
+    // one of meta1 & meta2 has suffix, but the other one doesn't have
+    if (meta1.getSuffix() == null ^ meta2.getSuffix() == null) {
+      return meta1.getSuffix() == null ? 1 : -1;
+    }
+
+    if (null != meta1.getSuffix()) {
+      result = comparePlaceholderString(meta1.getSuffix(), meta2.getSuffix());
+    }
+
+    return 0 == result ?
+        comparePlaceholderString(meta1.getPrefix(), meta2.getPrefix())
+        : result;
+  };
+
   private List<VertxRestAccessLogItemCreator> creators = new ArrayList<>();
 
-  /**
-   * All of the {@linkplain AccessLogItemMeta} will be wrapped into {@linkplain AccessLogItemMetaWrapper}.
-   */
   private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
 
   public VertxRestAccessLogPatternParser() {
@@ -44,6 +64,28 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
         accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
       }
     }
+    sortAccessLogItemMetaWrapper(accessLogItemMetaWrappers);
+  }
+
+  /**
+   * Behavior of this compare:
+   * 1. comparePlaceholderString("abc","bbc") < 0
+   * 2. comparePlaceholderString("abc","ab") < 0
+   * 3. comparePlaceholderString("abc","abc) = 0
+   */
+  public static int comparePlaceholderString(String s1, String s2) {
+    int result = s1.compareTo(s2);
+    if (0 == result) {
+      return result;
+    }
+
+    // there are two possible cases:
+    // 1. s1="ab", s2="def"
+    // 2. s1="ab", s2="abc"
+    // in the case1 just return the result, but int the case2 the result should be reversed
+    return result < 0 ?
+        (s2.startsWith(s1) ? -result : result)
+        : (s1.startsWith(s2) ? -result : result);
   }
 
   /**
@@ -57,6 +99,44 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
     return itemList;
   }
 
+  /**
+   * Sort all of the {@link AccessLogItemMetaWrapper}, the wrapper that is in front of the others has higher priority.
+   * <p/>
+   * Sort rule(priority decreased):
+   * <ol>
+   *   <li>compare the {@link AccessLogItemMeta#order}</li>
+   *   <li>compare the {@link AccessLogItemMeta#suffix} in lexicographic order, if one's suffix is start with
+   *   the other one's suffix, this one(who's suffix is longer) has higher priority</li>
+   *   <li>compare the {@link AccessLogItemMeta#prefix}, compare rule is the same as suffix.</li>
+   * </ol>
+   * <p/>
+   * e.g. given a list of {@link AccessLogItemMeta} like below:
+   * <ol>
+   * <li>(%ac{,}bcd)</li>
+   * <li>(%ac{,}bc)</li>
+   * <li>(%ac{,}a)</li>
+   * <li>(%ac,)</li>
+   * <li>(%b,)</li>
+   * <li>(%a)</li>
+   * <li>(%{,}b)</li>
+   * <li>(%{,}bc)</li>
+   * </ol>
+   * the result is:
+   * <ol>
+   * <li>(%ac{,}a)</li>
+   * <li>(%ac{,}bcd)</li>
+   * <li>(%ac{,}bc)</li>
+   * <li>(%{,}bc)</li>
+   * <li>(%{,}b)</li>
+   * <li>(%ac,)</li>
+   * <li>(%a)</li>
+   * <li>(%b,)</li>
+   * </ol>
+   */
+  private void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
+    accessLogItemMetaWrapperList.sort(accessLogItemMetaWrapperComparator);
+  }
+
   public static class AccessLogItemMetaWrapper {
     private AccessLogItemMeta accessLogItemMeta;
 
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
index c27503e..2fdcc2d 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/VertxRestAccessLogPatternParserTest.java
@@ -17,5 +17,113 @@
 
 package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
 
+import java.util.Comparator;
+import java.util.function.Function;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser.AccessLogItemMetaWrapper;
+import org.junit.Assert;
+import org.junit.Test;
+
 public class VertxRestAccessLogPatternParserTest {
-}
\ No newline at end of file
+
+  Comparator<AccessLogItemMetaWrapper> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaWrapperComparator;
+
+  Function<AccessLogItemMeta, AccessLogItemMetaWrapper> wrapper =
+      accessLogItemMeta -> new AccessLogItemMetaWrapper(accessLogItemMeta, null);
+
+  /**
+   * one factor test
+   */
+  @Test
+  public void testCompareMetaSimple() {
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, null, 0)),
+            wrapper.apply(new AccessLogItemMeta(null, null, 1))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
+            wrapper.apply(new AccessLogItemMeta(null, null))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
+            wrapper.apply(new AccessLogItemMeta(null, "}de"))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta(null, "}abc")),
+            wrapper.apply(new AccessLogItemMeta(null, "}ab"))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", null)),
+            wrapper.apply(new AccessLogItemMeta("%de", null))
+        ) < 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", null)),
+            wrapper.apply(new AccessLogItemMeta("%ab", null))
+        ) < 0
+    );
+    Assert.assertEquals(0, comparator.compare(
+        wrapper.apply(new AccessLogItemMeta("%abc", null)),
+        wrapper.apply(new AccessLogItemMeta("%abc", null))
+    ));
+  }
+
+  /**
+   * multiple factors test
+   */
+  @Test
+  public void testCompareMetaComplex() {
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%bcd", "}ab", 0)),
+            wrapper.apply(new AccessLogItemMeta("%abc", "}abc", 0))
+        ) > 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", null, 0)),
+            wrapper.apply(new AccessLogItemMeta("%bcd", "}ab", 0))
+        ) > 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%bcd", "}abc")),
+            wrapper.apply(new AccessLogItemMeta("%abc", "}abc"))
+        ) > 0
+    );
+    Assert.assertTrue(
+        comparator.compare(
+            wrapper.apply(new AccessLogItemMeta("%abc", "}abc", 1)),
+            wrapper.apply(new AccessLogItemMeta("%ab", "}ab", 0))
+        ) > 0
+    );
+  }
+
+  @Test
+  public void testComparePlaceholderString() {
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("abc", "bbc") < 0
+    );
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("abc", "ab") < 0
+    );
+    Assert.assertEquals(0, VertxRestAccessLogPatternParser.comparePlaceholderString("abc", "abc"));
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("bbc", "abc") > 0
+    );
+    Assert.assertTrue(
+        VertxRestAccessLogPatternParser.comparePlaceholderString("ab", "abc") > 0
+    );
+  }
+}

-- 
To stop receiving notification emails like this one, please contact
wujimin@apache.org.