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

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


The following commit(s) were added to refs/heads/master by this push:
     new 865e58052 [SCB-2883]support trace id header in response (#4348)
865e58052 is described below

commit 865e58052fbc926da107618c1b79bc1383639aa7
Author: liubao68 <bi...@qq.com>
AuthorDate: Fri May 24 08:48:26 2024 +0800

    [SCB-2883]support trace id header in response (#4348)
---
 .../common/rest/RestProducerInvocationFlow.java    |  2 +-
 .../rest/filter/inner/RestServerCodecFilter.java   | 23 ++++++++-------
 .../src/main/resources/microservice.yaml           |  5 ++++
 .../apache/servicecomb/samples/HelloWorldIT.java   | 15 ++++++++++
 .../servicecomb/edge/core/EdgeAddHeaderFilter.java | 33 +++++++++-------------
 5 files changed, 48 insertions(+), 30 deletions(-)

diff --git 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationFlow.java
 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationFlow.java
index b09406bd4..dab6d6f6d 100644
--- 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationFlow.java
+++ 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationFlow.java
@@ -48,7 +48,7 @@ public class RestProducerInvocationFlow extends 
ProducerInvocationFlow {
   protected Invocation sendCreateInvocationException(Throwable throwable) {
     try {
       Response response = Exceptions.toProducerResponse(null, throwable);
-      RestServerCodecFilter.encodeResponse(response, false, 
DEFAULT_PRODUCE_PROCESSOR, responseEx);
+      RestServerCodecFilter.encodeResponse(null, response, false, 
DEFAULT_PRODUCE_PROCESSOR, responseEx);
     } catch (Throwable e) {
       LOGGER.error("Failed to send response when prepare invocation failed, 
request uri:{}",
           requestEx.getRequestURI(), e);
diff --git 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
index b1b3c37b7..18a5d9d94 100644
--- 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
+++ 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
@@ -116,14 +116,14 @@ public class RestServerCodecFilter extends AbstractFilter 
implements ProviderFil
     HttpServletResponseEx responseEx = transportContext.getResponseEx();
     boolean download = isDownloadFileResponseType(invocation, response);
 
-    return encodeResponse(response, download, produceProcessor, responseEx)
+    return encodeResponse(invocation, response, download, produceProcessor, 
responseEx)
         .whenComplete((r, e) -> invocation.onEncodeResponseFinish());
   }
 
-  public static CompletableFuture<Response> encodeResponse(Response response, 
boolean download,
+  public static CompletableFuture<Response> encodeResponse(Invocation 
invocation, Response response, boolean download,
       ProduceProcessor produceProcessor, HttpServletResponseEx responseEx) {
     responseEx.setStatus(response.getStatusCode());
-    copyHeadersToHttpResponse(response.getHeaders(), responseEx);
+    copyHeadersToHttpResponse(invocation, response.getHeaders(), responseEx);
 
     boolean failed = response.getResult() instanceof InvocationException;
 
@@ -167,15 +167,18 @@ public class RestServerCodecFilter extends AbstractFilter 
implements ProviderFil
         invocation.findResponseType(response.getStatusCode()).getRawClass());
   }
 
-  public static void copyHeadersToHttpResponse(MultiMap headers, 
HttpServletResponseEx responseEx) {
-    if (headers == null) {
-      return;
+  public static void copyHeadersToHttpResponse(Invocation invocation, MultiMap 
headers,
+      HttpServletResponseEx responseEx) {
+    if (headers != null) {
+      headers.remove(CONTENT_LENGTH);
+      headers.remove(TRANSFER_ENCODING);
+      for (Entry<String, String> entry : headers.entries()) {
+        responseEx.addHeader(entry.getKey(), entry.getValue());
+      }
     }
 
-    headers.remove(CONTENT_LENGTH);
-    headers.remove(TRANSFER_ENCODING);
-    for (Entry<String, String> entry : headers.entries()) {
-      responseEx.addHeader(entry.getKey(), entry.getValue());
+    if (invocation != null && responseEx.getHeader(CoreConst.TRACE_ID_NAME) == 
null) {
+      responseEx.addHeader(CoreConst.TRACE_ID_NAME, invocation.getTraceId());
     }
   }
 }
diff --git a/demo/demo-filter/filter-edge/src/main/resources/microservice.yaml 
b/demo/demo-filter/filter-edge/src/main/resources/microservice.yaml
index 034b8cd04..d1730b7fe 100644
--- a/demo/demo-filter/filter-edge/src/main/resources/microservice.yaml
+++ b/demo/demo-filter/filter-edge/src/main/resources/microservice.yaml
@@ -30,6 +30,11 @@ servicecomb:
     server:
       compression: true
 
+  edge:
+    filter:
+      addHeader:
+        allowedHeaders: X-B3-TraceId
+
   invocation:
     exception:
       print-stack-trace: true
diff --git 
a/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
 
b/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
index c24a8796c..97e883fb4 100644
--- 
a/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
+++ 
b/demo/demo-zookeeper/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
@@ -19,7 +19,12 @@ package org.apache.servicecomb.samples;
 
 import org.apache.servicecomb.demo.CategorizedTestCase;
 import org.apache.servicecomb.demo.TestMgr;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Component;
+import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestOperations;
 import org.springframework.web.client.RestTemplate;
 
@@ -49,5 +54,15 @@ public class HelloWorldIT implements CategorizedTestCase {
     String result = template
         .getForObject(Config.GATEWAY_URL + "/sayHello?name=World", 
String.class);
     TestMgr.check("Hello World", result);
+
+    // test trace id added
+    MultiValueMap<String, String> headers = new HttpHeaders();
+    headers.add("X-B3-TraceId", "81de2eb7691c2bbb");
+    HttpEntity<Object> entity = new HttpEntity(headers);
+    ResponseEntity<String> response =
+        template.exchange(Config.GATEWAY_URL + "/sayHello?name=World", 
HttpMethod.GET, entity, String.class);
+    TestMgr.check(1, response.getHeaders().get("X-B3-TraceId").size());
+    TestMgr.check("81de2eb7691c2bbb", 
response.getHeaders().getFirst("X-B3-TraceId"));
+    TestMgr.check("Hello World", response.getBody());
   }
 }
diff --git 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeAddHeaderFilter.java
 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeAddHeaderFilter.java
index a0897b876..92594e615 100644
--- 
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeAddHeaderFilter.java
+++ 
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeAddHeaderFilter.java
@@ -20,10 +20,10 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
-import java.util.function.BiConsumer;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.config.ConfigurationChangedEvent;
+import org.apache.servicecomb.core.CoreConst;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.filter.AbstractFilter;
 import org.apache.servicecomb.core.filter.EdgeFilter;
@@ -42,16 +42,12 @@ public class EdgeAddHeaderFilter extends AbstractFilter 
implements EdgeFilter {
 
   private static final String PREFIX = "servicecomb.edge.filter.addHeader";
 
-  private static final String KEY_ENABLED = PREFIX + ".enabled";
-
   private static final String KEY_HEADERS = PREFIX + ".allowedHeaders";
 
   private final Environment environment;
 
   private List<String> publicHeaders = new ArrayList<>();
 
-  private boolean enabled = false;
-
   public EdgeAddHeaderFilter(Environment environment) {
     this.environment = environment;
     init();
@@ -70,12 +66,11 @@ public class EdgeAddHeaderFilter extends AbstractFilter 
implements EdgeFilter {
   }
 
   private void init() {
-    enabled = environment.getProperty(KEY_ENABLED, boolean.class, false);
-    String publicHeaderStr = environment.getProperty(KEY_HEADERS, "");
-    String[] split = publicHeaderStr.split(",");
-    if (split.length > 0) {
-      publicHeaders = Arrays.asList(split);
+    String publicHeaderStr = environment.getProperty(KEY_HEADERS);
+    if (StringUtils.isEmpty(publicHeaderStr)) {
+      return;
     }
+    publicHeaders = Arrays.asList(publicHeaderStr.split(","));
   }
 
   @Override
@@ -85,29 +80,29 @@ public class EdgeAddHeaderFilter extends AbstractFilter 
implements EdgeFilter {
 
   @Override
   public boolean enabledForTransport(String transport) {
-    return enabled;
+    return CoreConst.RESTFUL.equals(transport);
   }
 
   @Override
   public int getOrder() {
-    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1991;
+    return Filter.CONSUMER_LOAD_BALANCE_ORDER + 1995;
   }
 
   @Override
   public CompletableFuture<Response> onFilter(Invocation invocation, 
FilterNode nextNode) {
-    RestClientTransportContext transportContext = 
invocation.getTransportContext();
-    return CompletableFuture.completedFuture(null)
-        .thenAccept(v -> addHeaders(invocation, 
transportContext.getHttpClientRequest()::putHeader))
-        .thenCompose(v -> nextNode.onFilter(invocation));
-  }
+    if (publicHeaders.isEmpty()) {
+      return nextNode.onFilter(invocation);
+    }
 
-  public void addHeaders(Invocation invocation, BiConsumer<String, String> 
headerAdder) {
+    RestClientTransportContext transportContext = 
invocation.getTransportContext();
     HttpServletRequestEx oldRequest = invocation.getRequestEx();
     publicHeaders.forEach(key -> {
       String value = oldRequest.getHeader(key);
       if (StringUtils.isNotEmpty(value)) {
-        headerAdder.accept(key, value);
+        transportContext.getHttpClientRequest().putHeader(key, value);
       }
     });
+
+    return nextNode.onFilter(invocation);
   }
 }

Reply via email to