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:46 UTC
[incubator-servicecomb-java-chassis] 04/06: [SCB-616] finish parse
logic refactor
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 34cf795db6383e125f2802bd555dc3b6d42fef1d
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Sun May 27 22:34:13 2018 +0800
[SCB-616] finish parse logic refactor
---
.../rest/vertx/accesslog/AccessLogGenerator.java | 9 +-
.../accesslog/element/impl/ResponseSizeItem.java | 4 +
.../parser/impl/DefaultAccessLogItemCreator.java | 137 ++++++++++++
.../impl/VertxRestAccessLogPatternParser.java | 232 +++++++++++++++++++--
.../impl/VertxRestAccessLogPatternParserTest.java | 136 ++++++++++++
5 files changed, 505 insertions(+), 13 deletions(-)
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
index f05e8d4..a2079eb 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/AccessLogGenerator.java
@@ -17,7 +17,11 @@
package org.apache.servicecomb.transport.rest.vertx.accesslog;
+import java.util.List;
+
import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.VertxRestAccessLogPatternParser;
import io.vertx.ext.web.RoutingContext;
@@ -32,9 +36,12 @@ public class AccessLogGenerator {
*/
private AccessLogItem<RoutingContext>[] accessLogItems;
+ private AccessLogPatternParser<RoutingContext> accessLogPatternParser = new VertxRestAccessLogPatternParser();
+
@SuppressWarnings("unchecked")
public AccessLogGenerator(String rawPattern) {
- accessLogItems = new AccessLogItem[0];
+ List<AccessLogItem<RoutingContext>> accessLogItemList = accessLogPatternParser.parsePattern(rawPattern);
+ accessLogItems = accessLogItemList.toArray(new AccessLogItem[0]);
}
public String generateLog(AccessLogParam<RoutingContext> accessLogParam) {
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java
index 0d58226..cb43bd5 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/ResponseSizeItem.java
@@ -41,4 +41,8 @@ public class ResponseSizeItem implements AccessLogItem<RoutingContext> {
long bytesWritten = response.bytesWritten();
return 0 == bytesWritten ? zeroBytes : String.valueOf(bytesWritten);
}
+
+ public String getZeroBytes() {
+ return zeroBytes;
+ }
}
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java
new file mode 100644
index 0000000..6a2a6fd
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/parser/impl/DefaultAccessLogItemCreator.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
+
+import io.vertx.ext.web.RoutingContext;
+
+public class DefaultAccessLogItemCreator implements VertxRestAccessLogItemCreator {
+ private static final Map<String, AccessLogItem<RoutingContext>> SIMPLE_ACCESS_LOG_ITEM_MAP = new HashMap<>();
+
+ private static final List<AccessLogItemMeta> SUPPORTED_META_LIST = new ArrayList<>();
+
+ static {
+ AccessLogItem<RoutingContext> item = new HttpMethodItem();
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%m", item);
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-method", item);
+ item = new HttpStatusItem();
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%s", item);
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("sc-status", item);
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%T", new DurationSecondItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%D", new DurationMillisecondItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%h", new RemoteHostItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%v", new LocalHostItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%p", new LocalPortItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%B", new ResponseSizeItem("0"));
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%b", new ResponseSizeItem("-"));
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%r", new FirstLineOfRequestItem());
+ item = new UrlPathItem();
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%U", item);
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri-stem", item);
+ item = new QueryStringItem();
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%q", item);
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri-query", item);
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("cs-uri", new UrlPathWithQueryItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%H", new RequestProtocolItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%t", new DatetimeConfigurableItem());
+ SIMPLE_ACCESS_LOG_ITEM_MAP.put("%SCB-traceId", new TraceIdItem());
+
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%m", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-method", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%s", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("sc-status", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%T", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%D", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%h", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%v", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%p", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%B", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%b", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%r", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%U", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri-stem", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%q", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri-query", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("cs-uri", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%H", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%t", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%SCB-traceId", null));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}t"));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}i"));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}o"));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}C"));
+ SUPPORTED_META_LIST.add(new AccessLogItemMeta("%{", "}SCB-ctx"));
+ }
+
+ @Override
+ public AccessLogItem<RoutingContext> createItem(AccessLogItemMeta accessLogItemMeta, String config) {
+ if (null == accessLogItemMeta.getSuffix()) {
+ // For the simple AccessLogItem
+ return SIMPLE_ACCESS_LOG_ITEM_MAP.get(accessLogItemMeta.getPrefix());
+ }
+
+ // For the configurable AccessLogItem
+ switch (accessLogItemMeta.getSuffix()) {
+ case "}t":
+ return new DatetimeConfigurableItem(config);
+ case "}i":
+ return new RequestHeaderItem(config);
+ case "}o":
+ return new ResponseHeaderItem(config);
+ case "}C":
+ return new CookieItem(config);
+ case "}SCB-ctx":
+ return new InvocationContextItem(config);
+ default:
+ // unexpected situation
+ return null;
+ }
+ }
+
+ @Override
+ public List<AccessLogItemMeta> getAccessLogItemMeta() {
+ return SUPPORTED_META_LIST;
+ }
+}
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 5295f10..f299426 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
@@ -19,9 +19,11 @@ package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.PlainTextItem;
import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogItemMeta;
import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.AccessLogPatternParser;
import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.VertxRestAccessLogItemCreator;
@@ -59,6 +61,7 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
private List<AccessLogItemMetaWrapper> accessLogItemMetaWrappers = new ArrayList<>();
public VertxRestAccessLogPatternParser() {
+ creators.add(new DefaultAccessLogItemCreator());
for (VertxRestAccessLogItemCreator creator : creators) {
for (AccessLogItemMeta accessLogItemMeta : creator.getAccessLogItemMeta()) {
accessLogItemMetaWrappers.add(new AccessLogItemMetaWrapper(accessLogItemMeta, creator));
@@ -89,17 +92,6 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
}
/**
- * @param rawPattern The access log pattern string specified by users.
- * @return A list of {@linkplain AccessLogItem} which actually generate the content of access log.
- */
- @Override
- public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {
- List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();
- // the algorithm is unimplemented.
- 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):
@@ -133,10 +125,217 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
* <li>(%b,)</li>
* </ol>
*/
- private void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
+ public static void sortAccessLogItemMetaWrapper(List<AccessLogItemMetaWrapper> accessLogItemMetaWrapperList) {
accessLogItemMetaWrapperList.sort(accessLogItemMetaWrapperComparator);
}
+ /**
+ * @param rawPattern The access log pattern string specified by users.
+ * @return A list of {@linkplain AccessLogItem} which actually generate the content of access log.
+ */
+ @Override
+ public List<AccessLogItem<RoutingContext>> parsePattern(String rawPattern) {
+ List<AccessLogItemLocation> locationList = matchAccessLogItem(rawPattern);
+ locationList = fillInPlainTextLocation(rawPattern, locationList);
+
+ return convertToItemList(rawPattern, locationList);
+ }
+
+ /**
+ * Use the {@link #accessLogItemMetaWrappers} to match rawPattern.
+ * Return a list of {@link AccessLogItemLocation}.
+ * Plain text is ignored.
+ */
+ private List<AccessLogItemLocation> matchAccessLogItem(String rawPattern) {
+ List<AccessLogItemLocation> locationList = new ArrayList<>();
+ int cursor = 0;
+ while (cursor < rawPattern.length()) {
+ AccessLogItemLocation candidate = null;
+ for (AccessLogItemMetaWrapper wrapper : accessLogItemMetaWrappers) {
+ if (null != candidate && null == wrapper.getSuffix()) {
+ // TODO:
+ // if user define item("%{","}ab") and item("%{_","}abc") and the pattern is "%{_var}ab}abc"
+ // currently the result is item("%{","_var","}ab"), plaintext("}abc")
+ // is this acceptable?
+
+ // We've gotten an AccessLogItem with suffix, so there is no need to match those without suffix,
+ // just break this match loop
+ cursor = candidate.tail;
+ break;
+ }
+ if (rawPattern.startsWith(wrapper.getPrefix(), cursor)) {
+ if (null == wrapper.getSuffix()) {
+ // for simple type AccessLogItem, there is no need to try to match the next item.
+ candidate = new AccessLogItemLocation(cursor, wrapper);
+ cursor = candidate.tail;
+ break;
+ }
+ // for configurable type, like %{...}i, more check is needed
+ // e.g. "%{varName1}o ${varName2}i" should be divided into
+ // ResponseHeaderItem with varName="varName1" and RequestHeaderItem with varName="varName2"
+ // INSTEAD OF RequestHeaderItem with varName="varName1}o ${varName2"
+ int rear = rawPattern.indexOf(wrapper.getSuffix(), cursor);
+ if (rear < 0) {
+ continue;
+ }
+ if (null == candidate || rear < candidate.suffixIndex) {
+ candidate = new AccessLogItemLocation(cursor, rear, wrapper);
+ }
+ // There is a matched item which is in front of this item, so this item is ignored.
+ }
+ }
+
+ if (candidate == null) {
+ ++cursor;
+ continue;
+ }
+ locationList.add(candidate);
+ }
+
+ return locationList;
+ }
+
+ /**
+ * After processing of {@link #matchAccessLogItem(String)}, all of the placeholders of {@link AccessLogItem} have been
+ * picked out. So the rest part of rawPattern should be treated as plain text. Those parts will be located in this
+ * method and wrapped as {@link PlainTextItem}.
+ * @param rawPattern raw pattern string of access log
+ * @param locationList locations picked out by {@link #matchAccessLogItem(String)}
+ * @return all of the locations including {@link PlainTextItem}.
+ */
+ private List<AccessLogItemLocation> fillInPlainTextLocation(String rawPattern,
+ List<AccessLogItemLocation> locationList) {
+ List<AccessLogItemLocation> resultList = new ArrayList<>();
+ if (locationList.isEmpty()) {
+ resultList.add(createTextPlainItemLocation(0, rawPattern.length()));
+ return resultList;
+ }
+
+ Iterator<AccessLogItemLocation> itemLocationIterator = locationList.iterator();
+ AccessLogItemLocation previousItemLocation = itemLocationIterator.next();
+ if (previousItemLocation.prefixIndex > 0) {
+ resultList.add(createTextPlainItemLocation(0, previousItemLocation.prefixIndex));
+ }
+ resultList.add(previousItemLocation);
+
+ while (itemLocationIterator.hasNext()) {
+ AccessLogItemLocation thisItemLocation = itemLocationIterator.next();
+ if (previousItemLocation.tail < thisItemLocation.prefixIndex) {
+ resultList.add(createTextPlainItemLocation(previousItemLocation.tail, thisItemLocation.prefixIndex));
+ }
+ previousItemLocation = thisItemLocation;
+ resultList.add(previousItemLocation);
+ }
+
+ if (previousItemLocation.tail < rawPattern.length()) {
+ resultList.add(createTextPlainItemLocation(
+ previousItemLocation.tail,
+ rawPattern.length()));
+ }
+ return resultList;
+ }
+
+ private AccessLogItemLocation createTextPlainItemLocation(int front, int rear) {
+ return new AccessLogItemLocation(front, rear);
+ }
+
+ private List<AccessLogItem<RoutingContext>> convertToItemList(String rawPattern,
+ List<AccessLogItemLocation> locationList) {
+ List<AccessLogItem<RoutingContext>> itemList = new ArrayList<>();
+
+ for (AccessLogItemLocation accessLogItemLocation : locationList) {
+ AccessLogItemMetaWrapper accessLogItemMetaWrapper = accessLogItemLocation.accessLogItemMetaWrapper;
+ if (null == accessLogItemMetaWrapper) {
+ // a PlainTextItem location
+ itemList.add(new PlainTextItem(rawPattern.substring(
+ accessLogItemLocation.prefixIndex, accessLogItemLocation.tail
+ )));
+ continue;
+ }
+
+ itemList.add(
+ accessLogItemMetaWrapper.getVertxRestAccessLogItemCreator().createItem(
+ accessLogItemMetaWrapper.getAccessLogItemMeta(),
+ getConfigString(rawPattern, accessLogItemLocation))
+ );
+ }
+
+ return itemList;
+ }
+
+ private String getConfigString(String rawPattern, AccessLogItemLocation accessLogItemLocation) {
+ if (null == accessLogItemLocation.getSuffix()) {
+ // simple AccessLogItem
+ return null;
+ }
+
+ return rawPattern.substring(
+ accessLogItemLocation.prefixIndex + accessLogItemLocation.getPrefix().length(),
+ accessLogItemLocation.suffixIndex);
+ }
+
+ private static class AccessLogItemLocation {
+ /**
+ * prefixIndex = rawPattern.indexOf(prefix)
+ */
+ int prefixIndex;
+
+ /**
+ * suffixIndex = rawPattern.indexOf(suffix)
+ */
+ int suffixIndex;
+
+ /**
+ * tail = suffixIndex + suffix.length()
+ */
+ int tail;
+
+ AccessLogItemMetaWrapper accessLogItemMetaWrapper;
+
+ /**
+ * for {@link PlainTextItem} only
+ */
+ AccessLogItemLocation(int prefixIndex, int suffixIndex) {
+ this.prefixIndex = prefixIndex;
+ this.suffixIndex = suffixIndex;
+ this.tail = suffixIndex;
+ }
+
+ /**
+ * for configurable type AccessLogItem
+ */
+ AccessLogItemLocation(int prefixIndex, int suffixIndex, AccessLogItemMetaWrapper accessLogItemMetaWrapper) {
+ this.prefixIndex = prefixIndex;
+ this.suffixIndex = suffixIndex;
+ this.tail = suffixIndex + accessLogItemMetaWrapper.getSuffix().length();
+ this.accessLogItemMetaWrapper = accessLogItemMetaWrapper;
+ }
+
+ /**
+ * for simple type AccessLogItem
+ */
+ AccessLogItemLocation(int prefixIndex, AccessLogItemMetaWrapper accessLogItemMetaWrapper) {
+ this.prefixIndex = prefixIndex;
+ this.suffixIndex = prefixIndex + accessLogItemMetaWrapper.getPrefix().length();
+ this.tail = this.suffixIndex;
+ this.accessLogItemMetaWrapper = accessLogItemMetaWrapper;
+ }
+
+ public String getPrefix() {
+ if (null == accessLogItemMetaWrapper) {
+ return null;
+ }
+ return accessLogItemMetaWrapper.getPrefix();
+ }
+
+ public String getSuffix() {
+ if (null == accessLogItemMetaWrapper) {
+ return null;
+ }
+ return accessLogItemMetaWrapper.getSuffix();
+ }
+ }
+
public static class AccessLogItemMetaWrapper {
private AccessLogItemMeta accessLogItemMeta;
@@ -155,5 +354,14 @@ public class VertxRestAccessLogPatternParser implements AccessLogPatternParser<R
public VertxRestAccessLogItemCreator getVertxRestAccessLogItemCreator() {
return vertxRestAccessLogItemCreator;
}
+
+ public String getPrefix() {
+ return accessLogItemMeta.getPrefix();
+ }
+
+ public String getSuffix() {
+ return accessLogItemMeta.getSuffix();
+ }
}
}
+
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 2fdcc2d..0cfd2cd 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,15 +17,151 @@
package org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl;
+import static org.junit.Assert.assertEquals;
+
import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.TimeZone;
import java.util.function.Function;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.CookieItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DatetimeConfigurableItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationMillisecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.DurationSecondItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.FirstLineOfRequestItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpMethodItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.HttpStatusItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.InvocationContextItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.LocalPortItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.QueryStringItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RemoteHostItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.RequestProtocolItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseHeaderItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.ResponseSizeItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.TraceIdItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathItem;
+import org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl.UrlPathWithQueryItem;
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;
+import io.vertx.ext.web.RoutingContext;
+
public class VertxRestAccessLogPatternParserTest {
+ private static final String ROW_PATTERN = "[cs-method] %m %s%T%D%h%v%p%B%b%r%U%q"
+ + "cs-uri-stemcs-uri-querycs-uri%H%t%{yyyy MM dd HH:mm:ss zzz}t"
+ + "%{yyyy MM dd HH:mm:ss|GMT+0|en-US}t"
+ + "%{incoming-header}i"
+ + "%{outgoing-header}o"
+ + "%{cookie}C"
+ + "%SCB-traceId"
+ + "%{ctx}SCB-ctx";
+
+ private static VertxRestAccessLogPatternParser accessLogPatternParser = new VertxRestAccessLogPatternParser();
+
+ @Test
+ public void testParsePatternFullTest() {
+ List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(ROW_PATTERN);
+ assertEquals(28, result.size());
+
+ assertEquals("[", result.get(0).getFormattedItem(null));
+ assertEquals(HttpMethodItem.class, result.get(1).getClass());
+ assertEquals("] ", result.get(2).getFormattedItem(null));
+ assertEquals(HttpMethodItem.class, result.get(3).getClass());
+ assertEquals(" ", result.get(4).getFormattedItem(null));
+ assertEquals(HttpStatusItem.class, result.get(5).getClass());
+ assertEquals(DurationSecondItem.class, result.get(6).getClass());
+ assertEquals(DurationMillisecondItem.class, result.get(7).getClass());
+ assertEquals(RemoteHostItem.class, result.get(8).getClass());
+ assertEquals(LocalHostItem.class, result.get(9).getClass());
+ assertEquals(LocalPortItem.class, result.get(10).getClass());
+ assertEquals(ResponseSizeItem.class, result.get(11).getClass());
+ assertEquals("0", ((ResponseSizeItem) result.get(11)).getZeroBytes());
+ assertEquals(ResponseSizeItem.class, result.get(12).getClass());
+ assertEquals("-", ((ResponseSizeItem) result.get(12)).getZeroBytes());
+ assertEquals(FirstLineOfRequestItem.class, result.get(13).getClass());
+ assertEquals(UrlPathItem.class, result.get(14).getClass());
+ assertEquals(QueryStringItem.class, result.get(15).getClass());
+ assertEquals(UrlPathItem.class, result.get(16).getClass());
+ assertEquals(QueryStringItem.class, result.get(17).getClass());
+ assertEquals(UrlPathWithQueryItem.class, result.get(18).getClass());
+ assertEquals(RequestProtocolItem.class, result.get(19).getClass());
+ assertEquals(DatetimeConfigurableItem.class, result.get(20).getClass());
+ assertEquals(DatetimeConfigurableItem.DEFAULT_DATETIME_PATTERN,
+ ((DatetimeConfigurableItem) result.get(20)).getPattern());
+ assertEquals(DatetimeConfigurableItem.DEFAULT_LOCALE, ((DatetimeConfigurableItem) result.get(20)).getLocale());
+ assertEquals(TimeZone.getDefault(), ((DatetimeConfigurableItem) result.get(20)).getTimezone());
+ assertEquals("yyyy MM dd HH:mm:ss zzz", ((DatetimeConfigurableItem) result.get(21)).getPattern());
+ assertEquals(DatetimeConfigurableItem.DEFAULT_LOCALE, ((DatetimeConfigurableItem) result.get(21)).getLocale());
+ assertEquals(TimeZone.getDefault(), ((DatetimeConfigurableItem) result.get(21)).getTimezone());
+ assertEquals("yyyy MM dd HH:mm:ss", ((DatetimeConfigurableItem) result.get(22)).getPattern());
+ assertEquals(Locale.forLanguageTag("en-US"), ((DatetimeConfigurableItem) result.get(22)).getLocale());
+ assertEquals(TimeZone.getTimeZone("GMT+0"), ((DatetimeConfigurableItem) result.get(22)).getTimezone());
+ assertEquals(RequestHeaderItem.class, result.get(23).getClass());
+ assertEquals("incoming-header", ((RequestHeaderItem) result.get(23)).getVarName());
+ assertEquals(ResponseHeaderItem.class, result.get(24).getClass());
+ assertEquals("outgoing-header", ((ResponseHeaderItem) result.get(24)).getVarName());
+ assertEquals(CookieItem.class, result.get(25).getClass());
+ assertEquals("cookie", ((CookieItem) result.get(25)).getVarName());
+ assertEquals(TraceIdItem.class, result.get(26).getClass());
+ assertEquals(InvocationContextItem.class, result.get(27).getClass());
+ assertEquals("ctx", ((InvocationContextItem) result.get(27)).getVarName());
+ }
+
+ @Test
+ public void testParsePattern() {
+ String pattern = " %m cs-uri-stem %{response-header}o ";
+ List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(pattern);
+ assertEquals(7, result.size());
+
+ assertEquals(" ", result.get(0).getFormattedItem(null));
+ assertEquals(HttpMethodItem.class, result.get(1).getClass());
+ assertEquals(" ", result.get(2).getFormattedItem(null));
+ assertEquals(UrlPathItem.class, result.get(3).getClass());
+ assertEquals(" ", result.get(4).getFormattedItem(null));
+ assertEquals(ResponseHeaderItem.class, result.get(5).getClass());
+ assertEquals("response-header", ((ResponseHeaderItem) result.get(5)).getVarName());
+ assertEquals(" ", result.get(6).getFormattedItem(null));
+ }
+
+ @Test
+ public void testParsePatternWithNoBlank() {
+ String pattern = "%mcs-uri-stem%{response-header}o";
+ List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(pattern);
+ assertEquals(3, result.size());
+
+ assertEquals(HttpMethodItem.class, result.get(0).getClass());
+ assertEquals(UrlPathItem.class, result.get(1).getClass());
+ assertEquals(ResponseHeaderItem.class, result.get(2).getClass());
+ assertEquals("response-header", ((ResponseHeaderItem) result.get(2)).getVarName());
+ }
+
+ @Test
+ public void testParsePatternComplex() {
+ String pattern = "%m cs-uri-stem %{response-header}o abc cs-uri-query %s%{request} header}i plain cs-uri";
+ List<AccessLogItem<RoutingContext>> result = accessLogPatternParser.parsePattern(pattern);
+ assertEquals(12, result.size());
+
+ assertEquals(HttpMethodItem.class, result.get(0).getClass());
+ assertEquals(" ", result.get(1).getFormattedItem(null));
+ assertEquals(UrlPathItem.class, result.get(2).getClass());
+ assertEquals(" ", result.get(3).getFormattedItem(null));
+ assertEquals(ResponseHeaderItem.class, result.get(4).getClass());
+ assertEquals("response-header", ((ResponseHeaderItem) result.get(4)).getVarName());
+ assertEquals(" abc ", result.get(5).getFormattedItem(null));
+ assertEquals(QueryStringItem.class, result.get(6).getClass());
+ assertEquals(" ", result.get(7).getFormattedItem(null));
+ assertEquals(HttpStatusItem.class, result.get(8).getClass());
+ assertEquals(RequestHeaderItem.class, result.get(9).getClass());
+ assertEquals("request} header", ((RequestHeaderItem) result.get(9)).getVarName());
+ assertEquals(" plain ", result.get(10).getFormattedItem(null));
+ assertEquals(UrlPathWithQueryItem.class, result.get(11).getClass());
+ }
Comparator<AccessLogItemMetaWrapper> comparator = VertxRestAccessLogPatternParser.accessLogItemMetaWrapperComparator;
--
To stop receiving notification emails like this one, please contact
wujimin@apache.org.