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/01/09 07:38:51 UTC

[incubator-servicecomb-java-chassis] branch master updated (36cd7d6 -> 3a21eb3)

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 36cd7d6  fix DiscoveryTree is serviceId level, can not share across services.
     new d2b7480  [JAV-587] add traceId into invocation context
     new a208a3f  [JAV-587] add demo test about traceId
     new 3a21eb3  [JAV-587] fix CI error

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:
 .../common/rest/filter/tracing/TracingFilter.java  | 58 +++++++++-------
 ...servicecomb.common.rest.filter.HttpServerFilter |  2 +-
 .../rest/filter/tracing/TracingFilterTest.java     | 80 ++++++++++++++++++++++
 core/pom.xml                                       |  4 ++
 core/src/main/java/io/servicecomb/core/Const.java  |  4 +-
 .../core/tracing/BraveTraceIdGenerator.java        | 26 +++----
 .../servicecomb/core/tracing/TraceIdGenerator.java |  6 +-
 .../BraveTraceIdGeneratorTest.java}                | 26 +++----
 .../demo/jaxrs/server/CodeFirstJaxrs.java          | 11 ++-
 .../servicecomb/demo/pojo/client/PojoClient.java   | 43 +++++++++---
 .../io/servicecomb/demo/pojo/server/TestImpl.java  |  7 ++
 .../io/servicecomb/demo/CodeFirstRestTemplate.java | 30 ++++++--
 .../src/main/java/io/servicecomb/demo/TestMgr.java | 16 +++++
 .../main/java/io/servicecomb/demo/server/Test.java |  2 +
 .../main/resources/microservices/pojo/server.yaml  |  9 ++-
 .../client/CodeFirstRestTemplateSpringmvc.java     | 20 +++---
 .../demo/springmvc/server/CodeFirstSpringmvc.java  | 20 ++++--
 .../demo/pojo/test/endpoints/TestImpl.java         |  7 ++
 18 files changed, 277 insertions(+), 94 deletions(-)
 copy demo/demo-signature/src/main/java/io/servicecomb/demo/signature/ServerSignature.java => common/common-rest/src/main/java/io/servicecomb/common/rest/filter/tracing/TracingFilter.java (53%)
 copy {demo/demo-signature => common/common-rest}/src/main/resources/META-INF/services/io.servicecomb.common.rest.filter.HttpServerFilter (93%)
 create mode 100644 common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java
 copy swagger/swagger-invocation/invocation-core/src/test/java/io/servicecomb/swagger/invocation/models/Person.java => core/src/main/java/io/servicecomb/core/tracing/BraveTraceIdGenerator.java (70%)
 copy demo/demo-crossapp/crossapp-server/src/main/java/io/servicecomb/demo/crossapp/HelloWorld.java => core/src/main/java/io/servicecomb/core/tracing/TraceIdGenerator.java (88%)
 copy core/src/test/java/io/servicecomb/core/{consumer/TestReactiveResponseExecutor.java => tracing/BraveTraceIdGeneratorTest.java} (61%)

-- 
To stop receiving notification emails like this one, please contact
['"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>'].

[incubator-servicecomb-java-chassis] 01/03: [JAV-587] add traceId into invocation context

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 d2b7480cf7496af05938c468c9ef2980ef6ff773
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Thu Jan 4 12:00:59 2018 +0800

    [JAV-587] add traceId into invocation context
---
 .../common/rest/filter/tracing/TracingFilter.java  | 76 ++++++++++++++++++++
 ...servicecomb.common.rest.filter.HttpServerFilter | 18 +++++
 .../rest/filter/tracing/TracingFilterTest.java     | 80 ++++++++++++++++++++++
 core/pom.xml                                       |  4 ++
 core/src/main/java/io/servicecomb/core/Const.java  |  4 +-
 .../core/tracing/BraveTraceIdGenerator.java        | 32 +++++++++
 .../servicecomb/core/tracing/TraceIdGenerator.java | 22 ++++++
 .../core/tracing/BraveTraceIdGeneratorTest.java    | 39 +++++++++++
 8 files changed, 274 insertions(+), 1 deletion(-)

diff --git a/common/common-rest/src/main/java/io/servicecomb/common/rest/filter/tracing/TracingFilter.java b/common/common-rest/src/main/java/io/servicecomb/common/rest/filter/tracing/TracingFilter.java
new file mode 100644
index 0000000..8646c2b
--- /dev/null
+++ b/common/common-rest/src/main/java/io/servicecomb/common/rest/filter/tracing/TracingFilter.java
@@ -0,0 +1,76 @@
+/*
+ * 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 io.servicecomb.common.rest.filter.tracing;
+
+import org.springframework.util.StringUtils;
+
+import io.servicecomb.common.rest.filter.HttpServerFilter;
+import io.servicecomb.core.Const;
+import io.servicecomb.core.Invocation;
+import io.servicecomb.core.tracing.BraveTraceIdGenerator;
+import io.servicecomb.core.tracing.TraceIdGenerator;
+import io.servicecomb.foundation.vertx.http.HttpServletRequestEx;
+import io.servicecomb.foundation.vertx.http.HttpServletResponseEx;
+import io.servicecomb.swagger.invocation.Response;
+
+/**
+ * Ensure the invocation contains traceId
+ */
+public class TracingFilter implements HttpServerFilter {
+  private TraceIdGenerator traceIdGenerator = getTraceIdGenerator();
+
+  @Override
+  public int getOrder() {
+    return 0;
+  }
+
+  /**
+   * Ensure the invocation contains traceId
+   * @return {@code null}
+   */
+  @Override
+  public Response afterReceiveRequest(Invocation invocation, HttpServletRequestEx requestEx) {
+    if (!StringUtils.isEmpty(invocation.getContext(Const.TRACE_ID_NAME))) {
+      // if invocation context contains traceId, nothing needed to do
+      return null;
+    }
+
+    String traceId = requestEx.getHeader(Const.TRACE_ID_NAME);
+    if (!StringUtils.isEmpty(traceId)) {
+      // if request header contains traceId, move traceId into invocation context
+      invocation.addContext(Const.TRACE_ID_NAME, traceId);
+      return null;
+    }
+
+    // if traceId not found, generate a traceId
+    invocation.addContext(Const.TRACE_ID_NAME, traceIdGenerator.generateStringId());
+
+    return null;
+  }
+
+  /**
+   * nothing to do
+   */
+  @Override
+  public void beforeSendResponse(Invocation invocation, HttpServletResponseEx responseEx) {
+  }
+
+  protected TraceIdGenerator getTraceIdGenerator() {
+    return BraveTraceIdGenerator.INSTANCE;
+  }
+}
diff --git a/common/common-rest/src/main/resources/META-INF/services/io.servicecomb.common.rest.filter.HttpServerFilter b/common/common-rest/src/main/resources/META-INF/services/io.servicecomb.common.rest.filter.HttpServerFilter
new file mode 100644
index 0000000..dd2626f
--- /dev/null
+++ b/common/common-rest/src/main/resources/META-INF/services/io.servicecomb.common.rest.filter.HttpServerFilter
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+io.servicecomb.common.rest.filter.tracing.TracingFilter
diff --git a/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java b/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java
new file mode 100644
index 0000000..10bc13b
--- /dev/null
+++ b/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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 io.servicecomb.common.rest.filter.tracing;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.servicecomb.core.Const;
+import io.servicecomb.core.Invocation;
+import io.servicecomb.core.tracing.TraceIdGenerator;
+import io.servicecomb.foundation.vertx.http.HttpServletRequestEx;
+
+public class TracingFilterTest {
+  private static final TestTracingFilter FILTER = new TestTracingFilter();
+
+  @Test
+  public void testAfterReceiveRequestOnInvocationContainsTraceId() {
+    Invocation invocation = Mockito.mock(Invocation.class);
+    String traceId = "traceIdTest";
+    HttpServletRequestEx requestEx = Mockito.mock(HttpServletRequestEx.class);
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(traceId);
+
+    FILTER.afterReceiveRequest(invocation, requestEx);
+
+    Mockito.verify(requestEx, Mockito.times(0)).getHeader(Const.TRACE_ID_NAME);
+  }
+
+  @Test
+  public void testAfterReceiveRequestOnHeaderContainsTraceId() {
+    Invocation invocation = Mockito.mock(Invocation.class);
+    String traceId = "traceIdTest";
+    HttpServletRequestEx requestEx = Mockito.mock(HttpServletRequestEx.class);
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(null);
+    Mockito.when(requestEx.getHeader(Const.TRACE_ID_NAME)).thenReturn(traceId);
+
+    FILTER.afterReceiveRequest(invocation, requestEx);
+
+    Mockito.verify(invocation).addContext(Const.TRACE_ID_NAME, traceId);
+  }
+
+  @Test
+  public void testAfterReceiveRequestOnGenerateTraceId() {
+    Invocation invocation = Mockito.mock(Invocation.class);
+    HttpServletRequestEx requestEx = Mockito.mock(HttpServletRequestEx.class);
+
+    Mockito.when(invocation.getContext(Const.TRACE_ID_NAME)).thenReturn(null);
+    Mockito.when(requestEx.getHeader(Const.TRACE_ID_NAME)).thenReturn(null);
+
+    FILTER.afterReceiveRequest(invocation, requestEx);
+
+    Mockito.verify(invocation).addContext(Const.TRACE_ID_NAME, TestTracingFilter.TRACE_ID);
+  }
+
+  static class TestTracingFilter extends TracingFilter {
+
+    static final String TRACE_ID = "" + Long.MAX_VALUE;
+
+    @Override
+    protected TraceIdGenerator getTraceIdGenerator() {
+      return () -> TRACE_ID;
+    }
+  }
+}
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
index 573a489..ceee759 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -39,6 +39,10 @@
       <artifactId>foundation-metrics</artifactId>
     </dependency>
     <dependency>
+      <groupId>io.zipkin.brave</groupId>
+      <artifactId>brave</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.jmockit</groupId>
       <artifactId>jmockit</artifactId>
       <scope>provided</scope>
diff --git a/core/src/main/java/io/servicecomb/core/Const.java b/core/src/main/java/io/servicecomb/core/Const.java
index 63af71a..b0c2d7b 100644
--- a/core/src/main/java/io/servicecomb/core/Const.java
+++ b/core/src/main/java/io/servicecomb/core/Const.java
@@ -40,6 +40,8 @@ public final class Const {
   public static final String TARGET_MICROSERVICE = "x-cse-target-microservice";
 
   public static final String REMOTE_ADDRESS = "x-cse-remote-address";
-  
+
   public static final String AUTH_TOKEN = "x-cse-auth-rsatoken";
+
+  public static final String TRACE_ID_NAME = "X-B3-TraceId";
 }
diff --git a/core/src/main/java/io/servicecomb/core/tracing/BraveTraceIdGenerator.java b/core/src/main/java/io/servicecomb/core/tracing/BraveTraceIdGenerator.java
new file mode 100644
index 0000000..dbacc78
--- /dev/null
+++ b/core/src/main/java/io/servicecomb/core/tracing/BraveTraceIdGenerator.java
@@ -0,0 +1,32 @@
+/*
+ * 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 io.servicecomb.core.tracing;
+
+import brave.internal.Platform;
+
+public class BraveTraceIdGenerator implements TraceIdGenerator {
+  public static final BraveTraceIdGenerator INSTANCE = new BraveTraceIdGenerator();
+
+  @Override
+  public String generateStringId() {
+    return String.valueOf(Platform.get().nextTraceIdHigh());
+  }
+
+  private BraveTraceIdGenerator() {
+  }
+}
diff --git a/core/src/main/java/io/servicecomb/core/tracing/TraceIdGenerator.java b/core/src/main/java/io/servicecomb/core/tracing/TraceIdGenerator.java
new file mode 100644
index 0000000..43a4490
--- /dev/null
+++ b/core/src/main/java/io/servicecomb/core/tracing/TraceIdGenerator.java
@@ -0,0 +1,22 @@
+/*
+ * 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 io.servicecomb.core.tracing;
+
+public interface TraceIdGenerator {
+  String generateStringId();
+}
diff --git a/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java b/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
new file mode 100644
index 0000000..2815039
--- /dev/null
+++ b/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
@@ -0,0 +1,39 @@
+/*
+ * 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 io.servicecomb.core.tracing;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+public class BraveTraceIdGeneratorTest {
+
+  @Test
+  public void generateStringId() {
+    TraceIdGenerator traceIdGenerator = BraveTraceIdGenerator.INSTANCE;
+    assertNotEquals(traceIdGenerator.generateStringId(), traceIdGenerator.generateStringId());
+
+    String traceId = traceIdGenerator.generateStringId();
+    try {
+      Long.valueOf(traceId);
+    } catch (NumberFormatException e) {
+      fail("wrong traceId format: " + traceId);
+    }
+  }
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-java-chassis] 03/03: [JAV-587] fix CI error

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 3a21eb309be61e1716430be1875b45cbb7f244b3
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Thu Jan 4 15:28:20 2018 +0800

    [JAV-587] fix CI error
---
 .../java/io/servicecomb/demo/pojo/test/endpoints/TestImpl.java     | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/integration-tests/pojo-test/src/test/java/io/servicecomb/demo/pojo/test/endpoints/TestImpl.java b/integration-tests/pojo-test/src/test/java/io/servicecomb/demo/pojo/test/endpoints/TestImpl.java
index 91b4b43..f3e066d 100644
--- a/integration-tests/pojo-test/src/test/java/io/servicecomb/demo/pojo/test/endpoints/TestImpl.java
+++ b/integration-tests/pojo-test/src/test/java/io/servicecomb/demo/pojo/test/endpoints/TestImpl.java
@@ -20,10 +20,12 @@ package io.servicecomb.demo.pojo.test.endpoints;
 import java.util.Arrays;
 import java.util.List;
 
+import io.servicecomb.core.Const;
 import io.servicecomb.demo.server.Test;
 import io.servicecomb.demo.server.TestRequest;
 import io.servicecomb.demo.server.User;
 import io.servicecomb.provider.pojo.RpcSchema;
+import io.servicecomb.swagger.invocation.context.ContextUtils;
 import io.servicecomb.swagger.invocation.exception.InvocationException;
 
 @RpcSchema(schemaId = "server")
@@ -99,4 +101,9 @@ public class TestImpl implements Test {
     System.out.println("addString: " + result);
     return result;
   }
+
+  @Override
+  public String testTraceId() {
+    return ContextUtils.getInvocationContext().getContext(Const.TRACE_ID_NAME);
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-java-chassis] 02/03: [JAV-587] add demo test about traceId

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 a208a3f663d6ebc03ba79fe8897a7552c6e1c056
Author: yaohaishi <ya...@huawei.com>
AuthorDate: Thu Jan 4 12:04:43 2018 +0800

    [JAV-587] add demo test about traceId
---
 .../rest/filter/tracing/TracingFilterTest.java     |  2 +-
 .../core/tracing/BraveTraceIdGeneratorTest.java    |  2 +-
 .../demo/jaxrs/server/CodeFirstJaxrs.java          | 11 +++++-
 .../servicecomb/demo/pojo/client/PojoClient.java   | 43 ++++++++++++++++++----
 .../io/servicecomb/demo/pojo/server/TestImpl.java  |  7 ++++
 .../io/servicecomb/demo/CodeFirstRestTemplate.java | 30 +++++++++++++--
 .../src/main/java/io/servicecomb/demo/TestMgr.java | 16 ++++++++
 .../main/java/io/servicecomb/demo/server/Test.java |  2 +
 .../main/resources/microservices/pojo/server.yaml  |  9 ++++-
 .../client/CodeFirstRestTemplateSpringmvc.java     | 20 ++++------
 .../demo/springmvc/server/CodeFirstSpringmvc.java  | 20 ++++++----
 11 files changed, 126 insertions(+), 36 deletions(-)

diff --git a/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java b/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java
index 10bc13b..b7cdcbd 100644
--- a/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java
+++ b/common/common-rest/src/test/java/io/servicecomb/common/rest/filter/tracing/TracingFilterTest.java
@@ -77,4 +77,4 @@ public class TracingFilterTest {
       return () -> TRACE_ID;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java b/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
index 2815039..ad2231e 100644
--- a/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
+++ b/core/src/test/java/io/servicecomb/core/tracing/BraveTraceIdGeneratorTest.java
@@ -36,4 +36,4 @@ public class BraveTraceIdGeneratorTest {
       fail("wrong traceId format: " + traceId);
     }
   }
-}
\ No newline at end of file
+}
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/io/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/io/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java
index b566b29..6dd2810 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/java/io/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/io/servicecomb/demo/jaxrs/server/CodeFirstJaxrs.java
@@ -38,6 +38,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response.Status;
 
 import io.servicecomb.common.rest.codec.RestObjectMapper;
+import io.servicecomb.core.Const;
 import io.servicecomb.demo.compute.Person;
 import io.servicecomb.demo.ignore.InputModelForTestIgnore;
 import io.servicecomb.demo.ignore.OutputModelForTestIgnore;
@@ -70,10 +71,10 @@ public class CodeFirstJaxrs {
   public Response cseResponse(InvocationContext c1) {
     Response response = Response.createSuccess(Status.ACCEPTED, new User());
     Headers headers = response.getHeaders();
-    headers.addHeader("h1", "h1v " + c1.getContext().toString());
+    headers.addHeader("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     InvocationContext c2 = ContextUtils.getInvocationContext();
-    headers.addHeader("h2", "h2v " + c2.getContext().toString());
+    headers.addHeader("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     return response;
   }
@@ -202,4 +203,10 @@ public class CodeFirstJaxrs {
     }
     return "hello " + person.get("name");
   }
+
+  @Path("/traceId")
+  @GET
+  public String getTraceId() {
+    return ContextUtils.getInvocationContext().getContext(Const.TRACE_ID_NAME);
+  }
 }
diff --git a/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java
index 4272e0e..17ec6af 100644
--- a/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java
+++ b/demo/demo-pojo/pojo-client/src/main/java/io/servicecomb/demo/pojo/client/PojoClient.java
@@ -27,6 +27,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
 
+import io.servicecomb.core.Const;
 import io.servicecomb.core.CseContext;
 import io.servicecomb.core.provider.consumer.InvokerUtils;
 import io.servicecomb.demo.DemoConst;
@@ -40,11 +41,13 @@ import io.servicecomb.demo.smartcare.SmartCare;
 import io.servicecomb.foundation.common.utils.BeanUtils;
 import io.servicecomb.foundation.common.utils.Log4jUtils;
 import io.servicecomb.provider.pojo.RpcReference;
+import io.servicecomb.swagger.invocation.context.ContextUtils;
+import io.servicecomb.swagger.invocation.context.InvocationContext;
 import io.servicecomb.swagger.invocation.exception.InvocationException;
 
 @Component
 public class PojoClient {
-  private static Logger LOGGER = LoggerFactory.getLogger(PojoClient.class);
+  public static final byte buffer[] = new byte[1024];
 
   public static CodeFirstPojoClient codeFirstPojoClient;
 
@@ -58,9 +61,9 @@ public class PojoClient {
 
   public static Test testFromXml;
 
-  private static SmartCare smartcare;
+  private static Logger LOGGER = LoggerFactory.getLogger(PojoClient.class);
 
-  public static final byte buffer[] = new byte[1024];
+  private static SmartCare smartcare;
 
   static {
     Arrays.fill(buffer, (byte) 1);
@@ -70,11 +73,6 @@ public class PojoClient {
     PojoClient.testFromXml = testFromXml;
   }
 
-  @Inject
-  public void setCodeFirstPojoClient(CodeFirstPojoClient codeFirstPojoClient) {
-    PojoClient.codeFirstPojoClient = codeFirstPojoClient;
-  }
-
   public static void main(String[] args) throws Exception {
     Log4jUtils.init();
     BeanUtils.init();
@@ -110,9 +108,33 @@ public class PojoClient {
       testSmartCare(smartcare);
 
       testCommonInvoke(transport);
+
+      if ("rest".equals(transport)) {
+        testTraceIdOnNotSetBefore();
+      }
+
+      testTraceIdOnContextContainsTraceId();
     }
   }
 
+  /**
+   * Only in http transport, traceId will be set to invocation if null.
+   * But in highway, nothing done.
+   */
+  private static void testTraceIdOnNotSetBefore() {
+    String traceId = test.testTraceId();
+    TestMgr.checkNotEmpty(traceId);
+  }
+
+  private static void testTraceIdOnContextContainsTraceId() {
+    InvocationContext context = new InvocationContext();
+    context.addContext(Const.TRACE_ID_NAME, String.valueOf(Long.MIN_VALUE));
+    ContextUtils.setInvocationContext(context);
+    String traceId = test.testTraceId();
+    TestMgr.check(String.valueOf(Long.MIN_VALUE), traceId);
+    ContextUtils.removeInvocationContext();
+  }
+
   private static void testSmartCare(SmartCare smartCare) {
     Group group = new Group();
     group.setName("group0");
@@ -221,4 +243,9 @@ public class PojoClient {
 
     TestMgr.check("User [name=nameA,  users count:1, age=100, index=0]", result);
   }
+
+  @Inject
+  public void setCodeFirstPojoClient(CodeFirstPojoClient codeFirstPojoClient) {
+    PojoClient.codeFirstPojoClient = codeFirstPojoClient;
+  }
 }
diff --git a/demo/demo-pojo/pojo-server/src/main/java/io/servicecomb/demo/pojo/server/TestImpl.java b/demo/demo-pojo/pojo-server/src/main/java/io/servicecomb/demo/pojo/server/TestImpl.java
index 915467a..8040500 100644
--- a/demo/demo-pojo/pojo-server/src/main/java/io/servicecomb/demo/pojo/server/TestImpl.java
+++ b/demo/demo-pojo/pojo-server/src/main/java/io/servicecomb/demo/pojo/server/TestImpl.java
@@ -20,10 +20,12 @@ package io.servicecomb.demo.pojo.server;
 import java.util.Arrays;
 import java.util.List;
 
+import io.servicecomb.core.Const;
 import io.servicecomb.demo.server.Test;
 import io.servicecomb.demo.server.TestRequest;
 import io.servicecomb.demo.server.User;
 import io.servicecomb.provider.pojo.RpcSchema;
+import io.servicecomb.swagger.invocation.context.ContextUtils;
 import io.servicecomb.swagger.invocation.exception.InvocationException;
 
 @RpcSchema(schemaId = "server")
@@ -98,4 +100,9 @@ public class TestImpl implements Test {
     System.out.println("addString: " + result);
     return result;
   }
+
+  @Override
+  public String testTraceId() {
+    return ContextUtils.getInvocationContext().getContext(Const.TRACE_ID_NAME);
+  }
 }
diff --git a/demo/demo-schema/src/main/java/io/servicecomb/demo/CodeFirstRestTemplate.java b/demo/demo-schema/src/main/java/io/servicecomb/demo/CodeFirstRestTemplate.java
index 2db5565..5c5a274 100644
--- a/demo/demo-schema/src/main/java/io/servicecomb/demo/CodeFirstRestTemplate.java
+++ b/demo/demo-schema/src/main/java/io/servicecomb/demo/CodeFirstRestTemplate.java
@@ -28,12 +28,15 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.client.RestTemplate;
 
+import io.servicecomb.core.Const;
 import io.servicecomb.core.CseContext;
 import io.servicecomb.demo.compute.Person;
 import io.servicecomb.demo.ignore.InputModelForTestIgnore;
 import io.servicecomb.demo.ignore.OutputModelForTestIgnore;
 import io.servicecomb.demo.server.User;
 import io.servicecomb.serviceregistry.RegistryUtils;
+import io.servicecomb.swagger.invocation.context.ContextUtils;
+import io.servicecomb.swagger.invocation.context.InvocationContext;
 import io.vertx.core.json.JsonObject;
 
 public class CodeFirstRestTemplate {
@@ -65,8 +68,12 @@ public class CodeFirstRestTemplate {
       // TODO: highway unsupported until JAV-394 completed
       if (transport.equals("rest")) {
         testOnlyRest(template, cseUrlPrefix);
+        // only rest transport will set trace id
+        testTraceIdOnNotSetBefore(template, cseUrlPrefix);
       }
 
+      testTraceIdOnContextContainsTraceId(template, cseUrlPrefix);
+
       testRawJson(template, cseUrlPrefix);
     }
   }
@@ -123,13 +130,12 @@ public class CodeFirstRestTemplate {
   private void testCseResponse(String targetMicroserviceName, RestTemplate template,
       String cseUrlPrefix) {
     String srcMicroserviceName = RegistryUtils.getMicroservice().getServiceName();
-    String context = String.format("{x-cse-src-microservice=%s}", srcMicroserviceName);
 
     ResponseEntity<User> responseEntity =
         template.exchange(cseUrlPrefix + "cseResponse", HttpMethod.GET, null, User.class);
     TestMgr.check("User [name=nameA, age=100, index=0]", responseEntity.getBody());
-    TestMgr.check("h1v " + context, responseEntity.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v " + context, responseEntity.getHeaders().getFirst("h2"));
+    TestMgr.check("h1v " + srcMicroserviceName, responseEntity.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcMicroserviceName, responseEntity.getHeaders().getFirst("h2"));
     checkStatusCode(targetMicroserviceName, 202, responseEntity.getStatusCode());
   }
 
@@ -227,7 +233,7 @@ public class CodeFirstRestTemplate {
   protected void testModelFieldIgnore(RestTemplate template, String cseUrlPrefix) {
     InputModelForTestIgnore input = new InputModelForTestIgnore("input_id_rest", "input_id_content",
         new Person("inputSomeone"), new JsonObject("{\"InputJsonKey\" : \"InputJsonValue\"}"), () -> {
-        });
+    });
     OutputModelForTestIgnore output = template
         .postForObject(cseUrlPrefix + "ignore", input, OutputModelForTestIgnore.class);
 
@@ -249,4 +255,20 @@ public class CodeFirstRestTemplate {
     String output = template.postForObject(cseUrlPrefix + "rawJsonAnnotation", input, String.class);
     TestMgr.check("hello zyy", output);
   }
+
+  protected void testTraceIdOnNotSetBefore(RestTemplate template, String cseUrlPrefix) {
+    String traceIdUrl = cseUrlPrefix + "traceId";
+    String result = template.getForObject(traceIdUrl, String.class);
+    TestMgr.checkNotEmpty(result);
+  }
+
+  protected void testTraceIdOnContextContainsTraceId(RestTemplate template, String cseUrlPrefix) {
+    String traceIdUrl = cseUrlPrefix + "traceId";
+    InvocationContext invocationContext = new InvocationContext();
+    invocationContext.addContext(Const.TRACE_ID_NAME, String.valueOf(Long.MIN_VALUE));
+    ContextUtils.setInvocationContext(invocationContext);
+    String result = template.getForObject(traceIdUrl, String.class);
+    TestMgr.check(String.valueOf(Long.MIN_VALUE), result);
+    ContextUtils.removeInvocationContext();
+  }
 }
diff --git a/demo/demo-schema/src/main/java/io/servicecomb/demo/TestMgr.java b/demo/demo-schema/src/main/java/io/servicecomb/demo/TestMgr.java
index d74457b..16475b3 100644
--- a/demo/demo-schema/src/main/java/io/servicecomb/demo/TestMgr.java
+++ b/demo/demo-schema/src/main/java/io/servicecomb/demo/TestMgr.java
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
 
 public class TestMgr {
   private static final Logger LOGGER = LoggerFactory.getLogger(TestMgr.class);
@@ -47,6 +48,12 @@ public class TestMgr {
     }
   }
 
+  public static void checkNotEmpty(String real) {
+    if (StringUtils.isEmpty(real)) {
+      errorList.add(new Error(msg + " | unexpected null result, method is " + getCaller()));
+    }
+  }
+
   public static void summary() {
     if (errorList.isEmpty()) {
       LOGGER.info("............. test finished ............");
@@ -62,4 +69,13 @@ public class TestMgr {
   public static List<Throwable> errors() {
     return errorList;
   }
+
+  private static String getCaller() {
+    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+    if (stackTrace.length < 3) {
+      return null;
+    }
+    StackTraceElement stackTraceElement = stackTrace[3];
+    return stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
+  }
 }
diff --git a/demo/demo-schema/src/main/java/io/servicecomb/demo/server/Test.java b/demo/demo-schema/src/main/java/io/servicecomb/demo/server/Test.java
index c106816..6b93798 100644
--- a/demo/demo-schema/src/main/java/io/servicecomb/demo/server/Test.java
+++ b/demo/demo-schema/src/main/java/io/servicecomb/demo/server/Test.java
@@ -33,4 +33,6 @@ public interface Test {
   User splitParam(int index, User user);
 
   String addString(String[] strArr);
+
+  String testTraceId();
 }
diff --git a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
index 38e6fc0..493da59 100644
--- a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
+++ b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
@@ -176,7 +176,14 @@ paths:
           description: add string
           schema:
             type: string
-            
+  /testTraceId:
+    get:
+      operationId: testTraceId
+      responses:
+        200:
+          description: get trace id
+          schema:
+            type: string
 definitions:
   Error:
     type: object
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
index bc632f4..dd793f1 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
@@ -175,15 +175,15 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
 
     ResponseEntity<Date> responseEntity = intf.responseEntity(date);
     TestMgr.check(date, responseEntity.getBody());
-    TestMgr.check("h1v {x-cse-src-microservice=" + srcName + "}", responseEntity.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v {x-cse-src-microservice=" + srcName + "}", responseEntity.getHeaders().getFirst("h2"));
+    TestMgr.check("h1v " + srcName, responseEntity.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcName, responseEntity.getHeaders().getFirst("h2"));
 
     checkStatusCode("springmvc", 202, responseEntity.getStatusCode());
 
     Response cseResponse = intf.cseResponse();
     TestMgr.check("User [name=nameA, age=100, index=0]", cseResponse.getResult());
-    TestMgr.check("h1v {x-cse-src-microservice=" + srcName + "}", cseResponse.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v {x-cse-src-microservice=" + srcName + "}", cseResponse.getHeaders().getFirst("h2"));
+    TestMgr.check("h1v " + srcName, cseResponse.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcName, cseResponse.getHeaders().getFirst("h2"));
   }
 
   private void testResponseEntity(String microserviceName, RestTemplate template, String cseUrlPrefix) {
@@ -199,19 +199,15 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
     ResponseEntity<Date> responseEntity =
         template.exchange(cseUrlPrefix + "responseEntity", HttpMethod.POST, httpEntity, Date.class);
     TestMgr.check(date, responseEntity.getBody());
-    TestMgr.check("h1v {contextKey=contextValue, x-cse-src-microservice=" + srcName + "}",
-        responseEntity.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v {contextKey=contextValue, x-cse-src-microservice=" + srcName + "}",
-        responseEntity.getHeaders().getFirst("h2"));
+    TestMgr.check("h1v " + srcName, responseEntity.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcName, responseEntity.getHeaders().getFirst("h2"));
     checkStatusCode(microserviceName, 202, responseEntity.getStatusCode());
 
     responseEntity =
         template.exchange(cseUrlPrefix + "responseEntity", HttpMethod.PATCH, httpEntity, Date.class);
     TestMgr.check(date, responseEntity.getBody());
-    TestMgr.check("h1v {contextKey=contextValue, x-cse-src-microservice=" + srcName + "}",
-        responseEntity.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v {contextKey=contextValue, x-cse-src-microservice=" + srcName + "}",
-        responseEntity.getHeaders().getFirst("h2"));
+    TestMgr.check("h1v " + srcName, responseEntity.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcName, responseEntity.getHeaders().getFirst("h2"));
     checkStatusCode(microserviceName, 202, responseEntity.getStatusCode());
   }
 
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
index cfe4bc9..a244e03 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
@@ -56,6 +56,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.netflix.servo.monitor.Monitor;
 
 import io.servicecomb.common.rest.codec.RestObjectMapper;
+import io.servicecomb.core.Const;
 import io.servicecomb.demo.compute.Person;
 import io.servicecomb.demo.ignore.InputModelForTestIgnore;
 import io.servicecomb.demo.ignore.OutputModelForTestIgnore;
@@ -118,10 +119,10 @@ public class CodeFirstSpringmvc {
   @RequestMapping(path = "/responseEntity", method = RequestMethod.POST)
   public ResponseEntity<Date> responseEntity(InvocationContext c1, @RequestAttribute("date") Date date) {
     HttpHeaders headers = new HttpHeaders();
-    headers.add("h1", "h1v " + c1.getContext().toString());
+    headers.add("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     InvocationContext c2 = ContextUtils.getInvocationContext();
-    headers.add("h2", "h2v " + c2.getContext().toString());
+    headers.add("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     return new ResponseEntity<Date>(date, headers, HttpStatus.ACCEPTED);
   }
@@ -131,10 +132,10 @@ public class CodeFirstSpringmvc {
   @RequestMapping(path = "/responseEntity", method = RequestMethod.PATCH)
   public ResponseEntity<Date> responseEntityPATCH(InvocationContext c1, @RequestAttribute("date") Date date) {
     HttpHeaders headers = new HttpHeaders();
-    headers.add("h1", "h1v " + c1.getContext().toString());
+    headers.add("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     InvocationContext c2 = ContextUtils.getInvocationContext();
-    headers.add("h2", "h2v " + c2.getContext().toString());
+    headers.add("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     return new ResponseEntity<Date>(date, headers, HttpStatus.ACCEPTED);
   }
@@ -146,10 +147,10 @@ public class CodeFirstSpringmvc {
   public Response cseResponse(InvocationContext c1) {
     Response response = Response.createSuccess(Status.ACCEPTED, new User());
     Headers headers = response.getHeaders();
-    headers.addHeader("h1", "h1v " + c1.getContext().toString());
+    headers.addHeader("h1", "h1v " + c1.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     InvocationContext c2 = ContextUtils.getInvocationContext();
-    headers.addHeader("h2", "h2v " + c2.getContext().toString());
+    headers.addHeader("h2", "h2v " + c2.getContext().get(Const.SRC_MICROSERVICE).toString());
 
     return response;
   }
@@ -306,7 +307,7 @@ public class CodeFirstSpringmvc {
     return new OutputModelForTestIgnore("output_id", input.getInputId(), input.getContent(), input.getInputObject(),
         input.getInputJsonObject(), input.getInputIgnoreInterface(),
         new Person("outputSomeone"), new JsonObject("{\"OutputJsonKey\" : \"OutputJsonValue\"}"), () -> {
-        });
+    });
   }
 
   @SuppressWarnings("unchecked")
@@ -350,4 +351,9 @@ public class CodeFirstSpringmvc {
       throw new InvocationException(500, "500", "JsonProcessingException", e);
     }
   }
+
+  @GetMapping(path = "/traceId")
+  public String getTraceId() {
+    return ContextUtils.getInvocationContext().getContext(Const.TRACE_ID_NAME);
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.