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/04/26 01:53:39 UTC

[incubator-servicecomb-java-chassis] branch master updated (43cec89 -> 5348393)

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

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


    from 43cec89  [SCB-512] download support chinese and space in file name
     new 5e794ad  [SCB-516] fix accessLog traceId printing problem in EdgeService
     new 44e7867  [SCB-516] make zipkin.brave reuse traceId generated by ServiceComb
     new 5348393  [SCB-516] print access log in routingContext.response().endHandler(), generate traceId as hexadecimal string

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../core/tracing/BraveTraceIdGenerator.java        |  2 +-
 .../core/tracing/BraveTraceIdGeneratorTest.java    |  2 +-
 .../tracing/zipkin/ZipkinProviderDelegate.java     | 21 +++++-
 .../tracing/zipkin/ZipkinProviderDelegateTest.java | 78 ++++++++++++++++++++++
 .../transport/rest/vertx/RestServerVerticle.java   |  8 ++-
 .../vertx/accesslog/element/impl/TraceIdItem.java  | 28 ++++++--
 .../vertx/accesslog/impl/AccessLogHandler.java     |  2 +-
 .../rest/vertx/trace/TracePrepareHandler.java      | 29 ++++----
 .../accesslog/element/impl/TraceIdItemTest.java    | 40 ++++++++++-
 .../TracePrepareHandlerTest.java}                  | 58 ++++++++--------
 10 files changed, 212 insertions(+), 56 deletions(-)
 create mode 100644 handlers/handler-tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegateTest.java
 copy handlers/handler-bizkeeper/src/main/java/org/apache/servicecomb/bizkeeper/ReturnNullFallbackPolicy.java => transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandler.java (59%)
 copy transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/{accesslog/element/impl/UrlPathItemTest.java => trace/TracePrepareHandlerTest.java} (51%)

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

[incubator-servicecomb-java-chassis] 02/03: [SCB-516] make zipkin.brave reuse traceId generated by ServiceComb

Posted by wu...@apache.org.
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 44e786782b72451bbd179189c333b3c14c8d23af
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Mon Apr 23 22:34:31 2018 +0800

    [SCB-516] make zipkin.brave reuse traceId generated by ServiceComb
---
 .../tracing/zipkin/ZipkinProviderDelegate.java     | 21 +++++-
 .../tracing/zipkin/ZipkinProviderDelegateTest.java | 78 ++++++++++++++++++++++
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegate.java b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegate.java
index 0ef438e..60b83bf 100644
--- a/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegate.java
+++ b/handlers/handler-tracing-zipkin/src/main/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegate.java
@@ -17,8 +17,12 @@
 
 package org.apache.servicecomb.tracing.zipkin;
 
+import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.swagger.invocation.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
 
 import brave.Span;
 import brave.Tracing;
@@ -28,6 +32,7 @@ import brave.propagation.Propagation.Getter;
 import brave.propagation.TraceContext.Extractor;
 
 class ZipkinProviderDelegate implements ZipkinTracingDelegate {
+  private static final Logger LOG = LoggerFactory.getLogger(ZipkinProviderDelegate.class);
 
   private final HttpServerHandler<Invocation, Response> handler;
 
@@ -35,6 +40,20 @@ class ZipkinProviderDelegate implements ZipkinTracingDelegate {
 
   private final Extractor<Invocation> extractor;
 
+  public static final String SPAN_ID_HEADER_NAME = "X-B3-SpanId";
+
+  public static final String TRACE_ID_HEADER_NAME = Const.TRACE_ID_NAME;
+
+  private static final Getter<Invocation, String> INVOCATION_STRING_GETTER = (invocation, key) -> {
+    String extracted = invocation.getContext().get(key);
+    if (StringUtils.isEmpty(extracted) && SPAN_ID_HEADER_NAME.equals(key)) {
+      // use traceId as spanId to avoid brave's recreating traceId
+      extracted = invocation.getContext().get(TRACE_ID_HEADER_NAME);
+      LOG.debug("try to extract X-B3-SpanId, but the value is empty, replace with TraceId = [{}]", extracted);
+    }
+    return extracted;
+  };
+
   @SuppressWarnings("unchecked")
   ZipkinProviderDelegate(HttpTracing httpTracing) {
     this.httpTracing = httpTracing;
@@ -63,6 +82,6 @@ class ZipkinProviderDelegate implements ZipkinTracingDelegate {
   }
 
   private Getter<Invocation, String> extractor() {
-    return (invocation, key) -> invocation.getContext().get(key);
+    return INVOCATION_STRING_GETTER;
   }
 }
diff --git a/handlers/handler-tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegateTest.java b/handlers/handler-tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegateTest.java
new file mode 100644
index 0000000..1ff3f98
--- /dev/null
+++ b/handlers/handler-tracing-zipkin/src/test/java/org/apache/servicecomb/tracing/zipkin/ZipkinProviderDelegateTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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.tracing.zipkin;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.core.Invocation;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import brave.propagation.Propagation.Getter;
+import mockit.Deencapsulation;
+
+public class ZipkinProviderDelegateTest {
+  @Test
+  public void testGetterOnGetSpanId() {
+    Getter<Invocation, String> getter = Deencapsulation
+        .getField(ZipkinProviderDelegate.class, "INVOCATION_STRING_GETTER");
+
+    Invocation invocation = Mockito.mock(Invocation.class);
+    Map<String, String> context = new HashMap<>();
+
+    Mockito.when(invocation.getContext()).thenReturn(context);
+
+    // if there is no spanId or traceId, then result is null
+    String spanId = getter.get(invocation, ZipkinProviderDelegate.SPAN_ID_HEADER_NAME);
+    Assert.assertNull(spanId);
+
+    // if there is no spanId but traceId, then traceId will be returned as result
+    final String testTraceId = "testTraceId";
+    context.put(ZipkinProviderDelegate.TRACE_ID_HEADER_NAME, testTraceId);
+    spanId = getter.get(invocation, ZipkinProviderDelegate.SPAN_ID_HEADER_NAME);
+    Assert.assertEquals(testTraceId, spanId);
+
+    // if there is spanId, then spanId will be returned
+    final String testSpanId = "testSpanId";
+    context.put(ZipkinProviderDelegate.SPAN_ID_HEADER_NAME, testSpanId);
+    spanId = getter.get(invocation, ZipkinProviderDelegate.SPAN_ID_HEADER_NAME);
+    Assert.assertEquals(testSpanId, spanId);
+  }
+
+  @Test
+  public void testGetterOnGetOtherContent() {
+    Getter<Invocation, String> getter = Deencapsulation
+        .getField(ZipkinProviderDelegate.class, "INVOCATION_STRING_GETTER");
+
+    Invocation invocation = Mockito.mock(Invocation.class);
+    Map<String, String> context = new HashMap<>();
+
+    Mockito.when(invocation.getContext()).thenReturn(context);
+
+    final String key = "key";
+    String value = getter.get(invocation, key);
+    Assert.assertNull(value);
+
+    final String expectedValue = "value";
+    context.put(key, expectedValue);
+    value = getter.get(invocation, key);
+    Assert.assertEquals(expectedValue, value);
+  }
+}

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

[incubator-servicecomb-java-chassis] 03/03: [SCB-516] print access log in routingContext.response().endHandler(), generate traceId as hexadecimal string

Posted by wu...@apache.org.
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 5348393b977f5e6a8eac87016dd1f969a7a1e6df
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Mon Apr 23 22:39:15 2018 +0800

    [SCB-516] print access log in routingContext.response().endHandler(), generate traceId as hexadecimal string
---
 .../java/org/apache/servicecomb/core/tracing/BraveTraceIdGenerator.java | 2 +-
 .../org/apache/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java  | 2 +-
 .../transport/rest/vertx/accesslog/impl/AccessLogHandler.java           | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/core/src/main/java/org/apache/servicecomb/core/tracing/BraveTraceIdGenerator.java b/core/src/main/java/org/apache/servicecomb/core/tracing/BraveTraceIdGenerator.java
index 95b01e9..c740b79 100644
--- a/core/src/main/java/org/apache/servicecomb/core/tracing/BraveTraceIdGenerator.java
+++ b/core/src/main/java/org/apache/servicecomb/core/tracing/BraveTraceIdGenerator.java
@@ -24,7 +24,7 @@ public class BraveTraceIdGenerator implements TraceIdGenerator {
 
   @Override
   public String generateStringId() {
-    return String.valueOf(Platform.get().nextTraceIdHigh());
+    return Long.toHexString(Platform.get().nextTraceIdHigh());
   }
 
   private BraveTraceIdGenerator() {
diff --git a/core/src/test/java/org/apache/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java b/core/src/test/java/org/apache/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
index b7197cc..d9c0bea 100644
--- a/core/src/test/java/org/apache/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
+++ b/core/src/test/java/org/apache/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
@@ -31,7 +31,7 @@ public class BraveTraceIdGeneratorTest {
 
     String traceId = traceIdGenerator.generateStringId();
     try {
-      Long.valueOf(traceId);
+      Long.parseLong(traceId, 16);
     } catch (NumberFormatException e) {
       fail("wrong traceId format: " + traceId);
     }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java
index 03f89cf..2acacb6 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/impl/AccessLogHandler.java
@@ -40,7 +40,7 @@ public class AccessLogHandler implements Handler<RoutingContext> {
     AccessLogParam<RoutingContext> accessLogParam = new AccessLogParam<>();
     accessLogParam.setStartMillisecond(System.currentTimeMillis()).setContextData(context);
 
-    context.addBodyEndHandler(v -> LOGGER.info(accessLogGenerator.generateLog(accessLogParam)));
+    context.response().endHandler(event -> LOGGER.info(accessLogGenerator.generateLog(accessLogParam)));
 
     context.next();
   }

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

[incubator-servicecomb-java-chassis] 01/03: [SCB-516] fix accessLog traceId printing problem in EdgeService

Posted by wu...@apache.org.
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 5e794ad1479d3305cb0d20d9b3c7fbccf06bcdc9
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Mon Apr 23 13:24:05 2018 +0800

    [SCB-516] fix accessLog traceId printing problem in EdgeService
---
 .../transport/rest/vertx/RestServerVerticle.java   |  8 ++-
 .../vertx/accesslog/element/impl/TraceIdItem.java  | 28 ++++++---
 .../rest/vertx/trace/TracePrepareHandler.java      | 38 +++++++++++
 .../accesslog/element/impl/TraceIdItemTest.java    | 40 +++++++++++-
 .../rest/vertx/trace/TracePrepareHandlerTest.java  | 73 ++++++++++++++++++++++
 5 files changed, 178 insertions(+), 9 deletions(-)

diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
index 79739ca..3eb679c 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestServerVerticle.java
@@ -30,6 +30,7 @@ import org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogConfiguration;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.impl.AccessLogHandler;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.parser.impl.DefaultAccessLogPatternParser;
+import org.apache.servicecomb.transport.rest.vertx.trace.TracePrepareHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,18 +69,23 @@ public class RestServerVerticle extends AbstractVerticle {
         return;
       }
       Router mainRouter = Router.router(vertx);
+      mountTracePrepareHandler(mainRouter);
       mountAccessLogHandler(mainRouter);
       initDispatcher(mainRouter);
       HttpServer httpServer = createHttpServer();
       httpServer.requestHandler(mainRouter::accept);
       startListen(httpServer, startFuture);
-    } catch(Throwable e) {
+    } catch (Throwable e) {
       // vert.x got some states that not print error and execute call back in VertexUtils.blockDeploy, we add a log our self.
       LOGGER.error("", e);
       throw e;
     }
   }
 
+  private void mountTracePrepareHandler(Router mainRouter) {
+    mainRouter.route().handler(new TracePrepareHandler());
+  }
+
   private void mountAccessLogHandler(Router mainRouter) {
     if (AccessLogConfiguration.INSTANCE.getAccessLogEnabled()) {
       String pattern = AccessLogConfiguration.INSTANCE.getAccesslogPattern();
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItem.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItem.java
index 98c4ead..a6118e2 100644
--- a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItem.java
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItem.java
@@ -19,7 +19,8 @@ package org.apache.servicecomb.transport.rest.vertx.accesslog.element.impl;
 
 import java.util.Map;
 
-import org.apache.servicecomb.common.rest.RestProducerInvocation;
+import org.apache.servicecomb.common.rest.AbstractRestInvocation;
+import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.AccessLogParam;
 import org.apache.servicecomb.transport.rest.vertx.accesslog.element.AccessLogItem;
 import org.springframework.util.StringUtils;
@@ -32,21 +33,34 @@ public class TraceIdItem implements AccessLogItem<RoutingContext> {
 
   @Override
   public String getFormattedItem(AccessLogParam<RoutingContext> accessLogParam) {
+    String traceId = getTraceIdFromInvocationContext(accessLogParam);
+    if (StringUtils.isEmpty(traceId)) {
+      traceId = accessLogParam.getContextData().request().getHeader(Const.TRACE_ID_NAME);
+    }
+
+    if (StringUtils.isEmpty(traceId)) {
+      return TRACE_ID_NOT_FOUND;
+    }
+
+    return traceId;
+  }
+
+  private String getTraceIdFromInvocationContext(AccessLogParam<RoutingContext> accessLogParam) {
     Map<String, Object> data = accessLogParam.getContextData().data();
     if (null == data) {
-      return TRACE_ID_NOT_FOUND;
+      return null;
     }
 
-    RestProducerInvocation restProducerInvocation = (RestProducerInvocation) data
+    AbstractRestInvocation invocation = (AbstractRestInvocation) data
         .get("servicecomb-rest-producer-invocation");
-    if (null == restProducerInvocation) {
-      return TRACE_ID_NOT_FOUND;
+    if (null == invocation) {
+      return null;
     }
 
-    String traceId = restProducerInvocation.getContext("X-B3-TraceId");
+    String traceId = invocation.getContext("X-B3-TraceId");
 
     if (StringUtils.isEmpty(traceId)) {
-      return TRACE_ID_NOT_FOUND;
+      return null;
     }
     return traceId;
   }
diff --git a/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandler.java b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandler.java
new file mode 100644
index 0000000..2f933a2
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandler.java
@@ -0,0 +1,38 @@
+/*
+ * 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.trace;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.tracing.BraveTraceIdGenerator;
+
+import io.vertx.core.Handler;
+import io.vertx.ext.web.RoutingContext;
+
+public class TracePrepareHandler implements Handler<RoutingContext> {
+  @Override
+  public void handle(RoutingContext context) {
+    String traceId = context.request().getHeader(Const.TRACE_ID_NAME);
+    if (StringUtils.isEmpty(traceId)) {
+      traceId = BraveTraceIdGenerator.INSTANCE.generateStringId();
+      context.request().headers().add(Const.TRACE_ID_NAME, traceId);
+    }
+
+    context.next();
+  }
+}
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItemTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItemTest.java
index 319fbf1..acf992a 100644
--- a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItemTest.java
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/accesslog/element/impl/TraceIdItemTest.java
@@ -30,6 +30,7 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.mockito.Mockito;
 
+import io.vertx.core.http.HttpServerRequest;
 import io.vertx.ext.web.RoutingContext;
 import mockit.Deencapsulation;
 
@@ -37,7 +38,7 @@ public class TraceIdItemTest {
   private static final TraceIdItem ELEMENT = new TraceIdItem();
 
   @Test
-  public void testGetFormattedElement() {
+  public void testGetFormattedElementFromInvocationContext() {
     AccessLogParam<RoutingContext> param = new AccessLogParam<>();
     RoutingContext routingContext = Mockito.mock(RoutingContext.class);
     Map<String, Object> data = new HashMap<>();
@@ -57,6 +58,30 @@ public class TraceIdItemTest {
   }
 
   @Test
+  public void testGetFormattedElementFromRequestHeader() {
+    AccessLogParam<RoutingContext> param = new AccessLogParam<>();
+    RoutingContext routingContext = Mockito.mock(RoutingContext.class);
+    Map<String, Object> data = new HashMap<>();
+    RestProducerInvocation restProducerInvocation = new RestProducerInvocation();
+    Invocation invocation = Mockito.mock(Invocation.class);
+    String traceIdTest = "traceIdTest";
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(null);
+    Deencapsulation.setField(restProducerInvocation, "invocation", invocation);
+    Mockito.when(routingContext.data()).thenReturn(data);
+    data.put("servicecomb-rest-producer-invocation", restProducerInvocation);
+
+    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+    Mockito.when(request.getHeader(Const.TRACE_ID_NAME)).thenReturn(traceIdTest);
+    Mockito.when(routingContext.request()).thenReturn(request);
+
+    param.setContextData(routingContext);
+
+    String result = ELEMENT.getFormattedItem(param);
+    Assert.assertThat(result, is(traceIdTest));
+  }
+
+  @Test
   public void testGetFormattedElementOnTraceIdNotFound() {
     AccessLogParam<RoutingContext> param = new AccessLogParam<>();
     RoutingContext routingContext = Mockito.mock(RoutingContext.class);
@@ -69,6 +94,10 @@ public class TraceIdItemTest {
     Mockito.when(routingContext.data()).thenReturn(data);
     data.put("servicecomb-rest-producer-invocation", restProducerInvocation);
 
+    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+    Mockito.when(request.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+    Mockito.when(routingContext.request()).thenReturn(request);
+
     param.setContextData(routingContext);
 
     String result = ELEMENT.getFormattedItem(param);
@@ -86,6 +115,11 @@ public class TraceIdItemTest {
     Map<String, Object> data = new HashMap<>();
 
     Mockito.when(routingContext.data()).thenReturn(data);
+
+    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+    Mockito.when(request.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+    Mockito.when(routingContext.request()).thenReturn(request);
+
     param.setContextData(routingContext);
 
     String result = ELEMENT.getFormattedItem(param);
@@ -97,6 +131,10 @@ public class TraceIdItemTest {
     AccessLogParam<RoutingContext> param = new AccessLogParam<>();
     RoutingContext routingContext = Mockito.mock(RoutingContext.class);
 
+    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+    Mockito.when(request.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+    Mockito.when(routingContext.request()).thenReturn(request);
+
     param.setContextData(routingContext);
     Mockito.when(routingContext.data()).thenReturn(null);
 
diff --git a/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandlerTest.java b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandlerTest.java
new file mode 100644
index 0000000..3ab1d06
--- /dev/null
+++ b/transports/transport-rest/transport-rest-vertx/src/test/java/org/apache/servicecomb/transport/rest/vertx/trace/TracePrepareHandlerTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.trace;
+
+import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.core.tracing.BraveTraceIdGenerator;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.MultiMap;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.core.http.impl.headers.VertxHttpHeaders;
+import io.vertx.ext.web.RoutingContext;
+import mockit.Expectations;
+
+public class TracePrepareHandlerTest {
+  private static final TracePrepareHandler HANDLER = new TracePrepareHandler();
+
+  @Test
+  public void handleWhenTraceIdExists() {
+    RoutingContext context = Mockito.mock(RoutingContext.class);
+    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+    String traceId = "testTraceId";
+
+    Mockito.when(context.request()).thenReturn(request);
+    Mockito.when(request.getHeader(Const.TRACE_ID_NAME)).thenReturn(traceId);
+
+    HANDLER.handle(context);
+
+    Mockito.verify(request, Mockito.times(0)).headers();
+  }
+
+  @Test
+  public void handleWhenSetNewTraceId() {
+    RoutingContext context = Mockito.mock(RoutingContext.class);
+    HttpServerRequest request = Mockito.mock(HttpServerRequest.class);
+    String traceId = "testTraceId";
+    MultiMap multimapHeader = new VertxHttpHeaders();
+
+    new Expectations(BraveTraceIdGenerator.class) {
+      {
+        BraveTraceIdGenerator.INSTANCE.generateStringId();
+        result = traceId;
+      }
+    };
+
+    Mockito.when(context.request()).thenReturn(request);
+    Mockito.when(request.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+    Mockito.when(request.headers()).thenReturn(multimapHeader);
+
+    HANDLER.handle(context);
+
+    Mockito.verify(request, Mockito.times(1)).headers();
+    Assert.assertEquals(1, multimapHeader.size());
+    Assert.assertEquals(traceId, multimapHeader.get(Const.TRACE_ID_NAME));
+  }
+}

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