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:41 UTC

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

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.