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); } }