From 8092235990f1231a7c1a99b99a22de085ca00cef Mon Sep 17 00:00:00 2001 From: "f.shim" Date: Fri, 27 Mar 2026 12:07:08 +0700 Subject: [PATCH 1/5] Remove OpenTelemetry --- pom.xml | 22 - woody-api/pom.xml | 17 - .../woody/api/AbstractClientBuilder.java | 1 - .../woody/api/AbstractServiceBuilder.java | 1 - .../dev/vality/woody/api/ClientBuilder.java | 1 - .../java/dev/vality/woody/api/MDCUtils.java | 138 ++-- .../dev/vality/woody/api/ServiceBuilder.java | 1 - .../woody/api/flow/concurrent/WCallable.java | 7 +- .../woody/api/flow/concurrent/WRunnable.java | 7 +- .../vality/woody/api/trace/ContextSpan.java | 4 - .../dev/vality/woody/api/trace/TraceData.java | 129 ---- .../woody/api/trace/context/TraceContext.java | 28 - .../transport/TransportEventInterceptor.java | 22 - .../woody/api/MdcUtilsExtendedTest.java | 2 - .../flow/concurrent/TestMDCInConcurent.java | 15 +- .../interceptor/ContextInterceptorTest.java | 3 - woody-thrift/pom.xml | 4 - .../impl/http/THSpawnClientBuilder.java | 1 - .../thrift/impl/http/TraceParentUtils.java | 27 - .../ext/TransportExtensionBundles.java | 82 --- .../impl/http/transport/THttpHeader.java | 2 - .../woody/thrift/impl/http/AbstractTest.java | 12 - .../woody/thrift/impl/http/MDCLogTest.java | 15 - .../impl/http/MetadataMdcPropagationTest.java | 277 -------- .../http/TestClientAndServerHttpHeaders.java | 63 -- .../http/TraceLifecycleIntegrationTest.java | 607 ------------------ .../http/error/THProviderErrorMapperTest.java | 3 - 27 files changed, 50 insertions(+), 1441 deletions(-) delete mode 100644 woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/TraceParentUtils.java delete mode 100644 woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java delete mode 100644 woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TraceLifecycleIntegrationTest.java diff --git a/pom.xml b/pom.xml index 0608f425..2dd406fd 100644 --- a/pom.xml +++ b/pom.xml @@ -46,8 +46,6 @@ UTF-8 11 11 - 1.49.0 - 1.37.0 @@ -68,26 +66,6 @@ slf4j-api 1.7.36 - - io.opentelemetry.semconv - opentelemetry-semconv - ${opentelemetry-semconv.version} - - - io.opentelemetry - opentelemetry-api - ${opentelemetry.version} - - - io.opentelemetry - opentelemetry-sdk - ${opentelemetry.version} - - - io.opentelemetry - opentelemetry-exporter-otlp - ${opentelemetry.version} - diff --git a/woody-api/pom.xml b/woody-api/pom.xml index 0197580d..4b4966b0 100644 --- a/woody-api/pom.xml +++ b/woody-api/pom.xml @@ -51,23 +51,6 @@ commons-pool2 2.12.1 - - - io.opentelemetry - opentelemetry-api - - - io.opentelemetry - opentelemetry-sdk - - - io.opentelemetry - opentelemetry-exporter-otlp - - - io.opentelemetry.semconv - opentelemetry-semconv - junit diff --git a/woody-api/src/main/java/dev/vality/woody/api/AbstractClientBuilder.java b/woody-api/src/main/java/dev/vality/woody/api/AbstractClientBuilder.java index c10e6018..e6ae846f 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/AbstractClientBuilder.java +++ b/woody-api/src/main/java/dev/vality/woody/api/AbstractClientBuilder.java @@ -12,7 +12,6 @@ import dev.vality.woody.api.trace.ContextSpan; import dev.vality.woody.api.proxy.tracer.*; import dev.vality.woody.api.trace.context.TraceContext; -import io.opentelemetry.sdk.resources.Resource; import java.net.URI; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/woody-api/src/main/java/dev/vality/woody/api/AbstractServiceBuilder.java b/woody-api/src/main/java/dev/vality/woody/api/AbstractServiceBuilder.java index 5c57c1b9..fd968135 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/AbstractServiceBuilder.java +++ b/woody-api/src/main/java/dev/vality/woody/api/AbstractServiceBuilder.java @@ -5,7 +5,6 @@ import dev.vality.woody.api.proxy.ProxyFactory; import dev.vality.woody.api.proxy.SingleTargetProvider; import dev.vality.woody.api.proxy.tracer.*; -import io.opentelemetry.sdk.resources.Resource; import java.util.concurrent.atomic.AtomicBoolean; diff --git a/woody-api/src/main/java/dev/vality/woody/api/ClientBuilder.java b/woody-api/src/main/java/dev/vality/woody/api/ClientBuilder.java index 6b91b783..6e5a4e85 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/ClientBuilder.java +++ b/woody-api/src/main/java/dev/vality/woody/api/ClientBuilder.java @@ -2,7 +2,6 @@ import dev.vality.woody.api.event.ClientEventListener; import dev.vality.woody.api.generator.IdGenerator; -import io.opentelemetry.sdk.resources.Resource; import java.net.URI; diff --git a/woody-api/src/main/java/dev/vality/woody/api/MDCUtils.java b/woody-api/src/main/java/dev/vality/woody/api/MDCUtils.java index 21fe75c7..50af1fda 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/MDCUtils.java +++ b/woody-api/src/main/java/dev/vality/woody/api/MDCUtils.java @@ -16,9 +16,6 @@ public class MDCUtils { public static final String SPAN_ID = "span_id"; - public static final String OTEL_TRACE_ID = "otel_trace_id"; - public static final String OTEL_SPAN_ID = "otel_span_id"; - public static final String OTEL_TRACE_FLAGS = "otel_trace_flags"; public static final String TRACE_ID = "trace_id"; public static final String PARENT_ID = "parent_id"; public static final String DEADLINE = "deadline"; @@ -37,61 +34,40 @@ public static void putTraceData(TraceData traceData, ContextSpan contextSpan) { return; } - io.opentelemetry.api.trace.Span otelSpan = traceData.getOtelSpan(); - io.opentelemetry.api.trace.SpanContext spanContext = otelSpan != null ? otelSpan.getSpanContext() : null; - - populateSpanIdentifiers(contextSpan.getSpan(), otelSpan); - populateOtelIdentifiers(spanContext, otelSpan); + populateSpanIdentifiers(contextSpan.getSpan()); boolean updatingClientSpan = traceData.getClientSpan() == contextSpan; boolean updatingServiceSpan = traceData.getServiceSpan() == contextSpan; if (isExtendedFieldsEnabled()) { if (updatingClientSpan) { - clearExtendedEntriesWithPrefix(TRACE_RPC_CLIENT_PREFIX, otelSpan); + clearExtendedEntriesWithPrefix(TRACE_RPC_CLIENT_PREFIX); } if (updatingServiceSpan) { - clearExtendedEntriesWithPrefix(TRACE_RPC_SERVER_PREFIX, otelSpan); + clearExtendedEntriesWithPrefix(TRACE_RPC_SERVER_PREFIX); } if (!updatingClientSpan && !updatingServiceSpan) { - clearExtendedEntries(false, otelSpan); + clearExtendedEntries(false); } - populateExtendedFields(traceData, otelSpan); + populateExtendedFields(traceData); } else { - clearExtendedEntries(false, otelSpan); + clearExtendedEntries(false); } - updateDeadlineEntries(traceData, contextSpan, otelSpan); - } - - private static void populateSpanIdentifiers(Span span, io.opentelemetry.api.trace.Span otelSpan) { - putTraceValue(otelSpan, SPAN_ID, span.getId()); - putTraceValue(otelSpan, TRACE_ID, span.getTraceId()); - putTraceValue(otelSpan, PARENT_ID, span.getParentId()); + updateDeadlineEntries(traceData, contextSpan); } - private static void populateOtelIdentifiers(io.opentelemetry.api.trace.SpanContext spanContext, - io.opentelemetry.api.trace.Span otelSpan) { - if (spanContext == null) { - putTraceValue(otelSpan, OTEL_TRACE_ID, null); - putTraceValue(otelSpan, OTEL_SPAN_ID, null); - putTraceValue(otelSpan, OTEL_TRACE_FLAGS, null); - return; - } - putTraceValue(otelSpan, OTEL_TRACE_ID, spanContext.getTraceId()); - putTraceValue(otelSpan, OTEL_SPAN_ID, spanContext.getSpanId()); - putTraceValue(otelSpan, OTEL_TRACE_FLAGS, - spanContext.getTraceFlags() != null ? spanContext.getTraceFlags().asHex() : null); + private static void populateSpanIdentifiers(Span span) { + putTraceValue(SPAN_ID, span.getId()); + putTraceValue(TRACE_ID, span.getTraceId()); + putTraceValue(PARENT_ID, span.getParentId()); } public static void removeTraceData() { MDC.remove(SPAN_ID); MDC.remove(TRACE_ID); - MDC.remove(OTEL_TRACE_ID); - MDC.remove(OTEL_SPAN_ID); - MDC.remove(OTEL_TRACE_FLAGS); MDC.remove(DEADLINE); - clearExtendedEntries(true, null); + clearExtendedEntries(true); } public static void putDeadline(TraceData traceData, ContextSpan contextSpan, Instant deadline) { @@ -99,14 +75,11 @@ public static void putDeadline(TraceData traceData, ContextSpan contextSpan, Ins removeDeadline(traceData, contextSpan); return; } - - io.opentelemetry.api.trace.Span otelSpan = traceData != null ? traceData.getOtelSpan() : null; - updateDeadlineEntries(traceData, contextSpan, otelSpan); + updateDeadlineEntries(traceData, contextSpan); } public static void removeDeadline(TraceData traceData, ContextSpan contextSpan) { - io.opentelemetry.api.trace.Span otelSpan = traceData != null ? traceData.getOtelSpan() : null; - updateDeadlineEntries(traceData, contextSpan, otelSpan); + updateDeadlineEntries(traceData, contextSpan); } public static void enableExtendedFields() { @@ -115,40 +88,38 @@ public static void enableExtendedFields() { public static void disableExtendedFields() { extendedFieldsEnabled = false; - clearExtendedEntries(false, null); + clearExtendedEntries(false); } public static boolean isExtendedFieldsEnabled() { return extendedFieldsEnabled; } - private static void populateExtendedFields(TraceData traceData, io.opentelemetry.api.trace.Span otelSpan) { - addSpanDetails(traceData.getClientSpan(), TRACE_RPC_CLIENT_PREFIX, otelSpan); - addSpanDetails(traceData.getServiceSpan(), TRACE_RPC_SERVER_PREFIX, otelSpan); + private static void populateExtendedFields(TraceData traceData) { + addSpanDetails(traceData.getClientSpan(), TRACE_RPC_CLIENT_PREFIX); + addSpanDetails(traceData.getServiceSpan(), TRACE_RPC_SERVER_PREFIX); } - private static void addSpanDetails(ContextSpan contextSpan, String prefix, - io.opentelemetry.api.trace.Span otelSpan) { + private static void addSpanDetails(ContextSpan contextSpan, String prefix) { if (contextSpan == null || !contextSpan.isFilled()) { return; } - addExtendedEntry(otelSpan, prefix + "service", resolveServiceName(contextSpan)); - addExtendedEntry(otelSpan, prefix + "function", resolveFunctionName(contextSpan)); - addExtendedEntry(otelSpan, prefix + "type", resolveCallType(contextSpan)); - addExtendedEntry(otelSpan, prefix + "event", resolveEvent(contextSpan)); - addExtendedEntry(otelSpan, prefix + "url", resolveEndpoint(contextSpan)); + addExtendedEntry(prefix + "service", resolveServiceName(contextSpan)); + addExtendedEntry(prefix + "function", resolveFunctionName(contextSpan)); + addExtendedEntry(prefix + "type", resolveCallType(contextSpan)); + addExtendedEntry(prefix + "event", resolveEvent(contextSpan)); + addExtendedEntry(prefix + "url", resolveEndpoint(contextSpan)); long duration = contextSpan.getSpan().getDuration(); if (duration > 0) { - addExtendedEntry(otelSpan, prefix + "execution_duration_ms", Long.toString(duration)); + addExtendedEntry(prefix + "execution_duration_ms", Long.toString(duration)); } - addCustomMetadataEntries(contextSpan, prefix + TRACE_RPC_METADATA_SUFFIX, otelSpan); + addCustomMetadataEntries(contextSpan, prefix + TRACE_RPC_METADATA_SUFFIX); } - private static void addCustomMetadataEntries(ContextSpan contextSpan, String prefix, - io.opentelemetry.api.trace.Span otelSpan) { + private static void addCustomMetadataEntries(ContextSpan contextSpan, String prefix) { Metadata metadata = contextSpan.getCustomMetadata(); if (metadata == null) { return; @@ -156,7 +127,7 @@ private static void addCustomMetadataEntries(ContextSpan contextSpan, String pre for (String key : metadata.getKeys()) { Object value = metadata.getValue(key); if (value != null) { - addExtendedEntry(otelSpan, prefix + key, Objects.toString(value)); + addExtendedEntry(prefix + key, Objects.toString(value)); } } } @@ -224,11 +195,11 @@ private static String formatEnum(Enum value) { return value == null ? null : value.name().toLowerCase(Locale.ROOT).replace('_', ' '); } - private static void addExtendedEntry(io.opentelemetry.api.trace.Span otelSpan, String key, String value) { + private static void addExtendedEntry(String key, String value) { if (key == null || value == null || value.isEmpty()) { return; } - putTraceValue(otelSpan, key, value); + putTraceValue(key, value); EXTENDED_MDC_KEYS.get().add(key); } @@ -236,24 +207,17 @@ private static void putMdcValue(String key, String value) { MDC.put(key, value != null ? value : ""); } - public static void removeExtendedEntry(io.opentelemetry.api.trace.Span otelSpan, String key) { + public static void removeExtendedEntry(String key) { MDC.remove(key); EXTENDED_MDC_KEYS.get().remove(key); - if (otelSpan != null) { - otelSpan.setAttribute(key, null); - } } - private static void updateDeadlineEntries(TraceData traceData, ContextSpan contextSpan, - io.opentelemetry.api.trace.Span otelSpan) { + private static void updateDeadlineEntries(TraceData traceData, ContextSpan contextSpan) { Instant activeDeadline = contextSpan != null ? ContextUtils.getDeadline(contextSpan) : null; if (activeDeadline != null) { - putTraceValue(otelSpan, DEADLINE, activeDeadline.toString()); + putTraceValue(DEADLINE, activeDeadline.toString()); } else { MDC.remove(DEADLINE); - if (otelSpan != null) { - otelSpan.setAttribute(DEADLINE, null); - } } boolean updatingClientSpan = traceData != null && traceData.getClientSpan() == contextSpan; @@ -261,54 +225,48 @@ private static void updateDeadlineEntries(TraceData traceData, ContextSpan conte if (!isExtendedFieldsEnabled()) { if (updatingClientSpan || (!updatingClientSpan && !updatingServiceSpan)) { - removeExtendedEntry(otelSpan, TRACE_RPC_CLIENT_PREFIX + "deadline"); + removeExtendedEntry(TRACE_RPC_CLIENT_PREFIX + "deadline"); } if (updatingServiceSpan || (!updatingClientSpan && !updatingServiceSpan)) { - removeExtendedEntry(otelSpan, TRACE_RPC_SERVER_PREFIX + "deadline"); + removeExtendedEntry(TRACE_RPC_SERVER_PREFIX + "deadline"); } return; } if (traceData != null) { if (updatingClientSpan) { - removeExtendedEntry(otelSpan, TRACE_RPC_CLIENT_PREFIX + "deadline"); + removeExtendedEntry(TRACE_RPC_CLIENT_PREFIX + "deadline"); } if (updatingServiceSpan) { - removeExtendedEntry(otelSpan, TRACE_RPC_SERVER_PREFIX + "deadline"); + removeExtendedEntry(TRACE_RPC_SERVER_PREFIX + "deadline"); } if (!updatingClientSpan && !updatingServiceSpan) { - removeExtendedEntry(otelSpan, TRACE_RPC_CLIENT_PREFIX + "deadline"); - removeExtendedEntry(otelSpan, TRACE_RPC_SERVER_PREFIX + "deadline"); + removeExtendedEntry(TRACE_RPC_CLIENT_PREFIX + "deadline"); + removeExtendedEntry(TRACE_RPC_SERVER_PREFIX + "deadline"); } - addDeadlineEntry(traceData.getClientSpan(), TRACE_RPC_CLIENT_PREFIX, otelSpan); - addDeadlineEntry(traceData.getServiceSpan(), TRACE_RPC_SERVER_PREFIX, otelSpan); + addDeadlineEntry(traceData.getClientSpan(), TRACE_RPC_CLIENT_PREFIX); + addDeadlineEntry(traceData.getServiceSpan(), TRACE_RPC_SERVER_PREFIX); } } - private static void addDeadlineEntry(ContextSpan span, String prefix, io.opentelemetry.api.trace.Span otelSpan) { + private static void addDeadlineEntry(ContextSpan span, String prefix) { if (span == null) { return; } Instant deadline = ContextUtils.getDeadline(span); if (deadline != null) { - addExtendedEntry(otelSpan, prefix + "deadline", deadline.toString()); + addExtendedEntry(prefix + "deadline", deadline.toString()); } } - private static void putTraceValue(io.opentelemetry.api.trace.Span otelSpan, String key, String value) { + private static void putTraceValue(String key, String value) { putMdcValue(key, value); - if (otelSpan != null) { - otelSpan.setAttribute(key, value != null ? value : ""); - } } - private static void clearExtendedEntries(boolean removeThreadLocal, io.opentelemetry.api.trace.Span otelSpan) { + private static void clearExtendedEntries(boolean removeThreadLocal) { Set keys = EXTENDED_MDC_KEYS.get(); for (String key : keys) { MDC.remove(key); - if (otelSpan != null) { - otelSpan.setAttribute(key, null); - } } if (removeThreadLocal) { @@ -318,17 +276,13 @@ private static void clearExtendedEntries(boolean removeThreadLocal, io.opentelem } } - private static void clearExtendedEntriesWithPrefix(String prefix, - io.opentelemetry.api.trace.Span otelSpan) { + private static void clearExtendedEntriesWithPrefix(String prefix) { Set keys = EXTENDED_MDC_KEYS.get(); Iterator iterator = keys.iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (key.startsWith(prefix)) { MDC.remove(key); - if (otelSpan != null) { - otelSpan.setAttribute(key, null); - } iterator.remove(); } } diff --git a/woody-api/src/main/java/dev/vality/woody/api/ServiceBuilder.java b/woody-api/src/main/java/dev/vality/woody/api/ServiceBuilder.java index 9730facf..f75ac382 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/ServiceBuilder.java +++ b/woody-api/src/main/java/dev/vality/woody/api/ServiceBuilder.java @@ -1,7 +1,6 @@ package dev.vality.woody.api; import dev.vality.woody.api.event.ServiceEventListener; -import io.opentelemetry.sdk.resources.Resource; public interface ServiceBuilder { ServiceBuilder withEventListener(ServiceEventListener listener); diff --git a/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WCallable.java b/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WCallable.java index 36ea2ff3..e58b9595 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WCallable.java +++ b/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WCallable.java @@ -56,15 +56,10 @@ public T call() throws Exception { clonedTraceData.getClientSpan().getSpan().setDeadline(deadline); } } - if (clonedTraceData.getServiceSpan().getSpan().isStarted()) { - clonedTraceData.clearPreserveOtelSpan(); - } else { + if (!clonedTraceData.getServiceSpan().getSpan().isStarted()) { clonedTraceData.getServiceSpan().getSpan().setTimestamp(0); clonedTraceData.getServiceSpan().getSpan().setDuration(0); - clonedTraceData.clearPreserveOtelSpan(); } - } else { - clonedTraceData.clearPreserveOtelSpan(); } TraceContext.setCurrentTraceData(clonedTraceData); diff --git a/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WRunnable.java b/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WRunnable.java index 8e2f0630..710acf98 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WRunnable.java +++ b/woody-api/src/main/java/dev/vality/woody/api/flow/concurrent/WRunnable.java @@ -55,15 +55,10 @@ public void run() { clonedTraceData.getClientSpan().getSpan().setDeadline(deadline); } } - if (clonedTraceData.getServiceSpan().getSpan().isStarted()) { - clonedTraceData.clearPreserveOtelSpan(); - } else { + if (!clonedTraceData.getServiceSpan().getSpan().isStarted()) { clonedTraceData.getServiceSpan().getSpan().setTimestamp(0); clonedTraceData.getServiceSpan().getSpan().setDuration(0); - clonedTraceData.clearPreserveOtelSpan(); } - } else { - clonedTraceData.clearPreserveOtelSpan(); } TraceContext.setCurrentTraceData(clonedTraceData); diff --git a/woody-api/src/main/java/dev/vality/woody/api/trace/ContextSpan.java b/woody-api/src/main/java/dev/vality/woody/api/trace/ContextSpan.java index 697f7f39..4a62be25 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/trace/ContextSpan.java +++ b/woody-api/src/main/java/dev/vality/woody/api/trace/ContextSpan.java @@ -1,9 +1,5 @@ package dev.vality.woody.api.trace; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.Tracer; -import io.opentelemetry.api.OpenTelemetry; - public class ContextSpan { protected final Span span; diff --git a/woody-api/src/main/java/dev/vality/woody/api/trace/TraceData.java b/woody-api/src/main/java/dev/vality/woody/api/trace/TraceData.java index e0e324d6..bd2ded1a 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/trace/TraceData.java +++ b/woody-api/src/main/java/dev/vality/woody/api/trace/TraceData.java @@ -1,33 +1,12 @@ package dev.vality.woody.api.trace; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.Scope; - public class TraceData { - public static final String OTEL_SERVER = "server"; - public static final String OTEL_CLIENT = "client"; - public static final String WOODY = "woody"; - private final ClientSpan clientSpan; private final ServiceSpan serviceSpan; - private Span otelSpan; - private Context otelContext; - private Scope activeScope; - private boolean ownsOtelSpan; - private boolean preserveOtelSpan; - private Context pendingParentContext; - private String inboundTraceParent; - private String inboundTraceState; - public TraceData() { this.clientSpan = new ClientSpan(); this.serviceSpan = new ServiceSpan(); - setPendingParentContext(Context.root()); - startPlaceholderSpan(); } public TraceData(TraceData oldTraceData) { @@ -39,14 +18,6 @@ public TraceData(TraceData oldTraceData, boolean copyCustomServiceMetadata) { ? new ClientSpan(oldTraceData.clientSpan, oldTraceData.serviceSpan.getCustomMetadata()) : oldTraceData.clientSpan.cloneObject(); this.serviceSpan = oldTraceData.serviceSpan.cloneObject(); - adoptOtelContext(oldTraceData.getOtelContext()); - this.otelSpan = oldTraceData.otelSpan; - this.ownsOtelSpan = false; - this.activeScope = null; - this.pendingParentContext = oldTraceData.pendingParentContext; - this.inboundTraceParent = oldTraceData.inboundTraceParent; - this.inboundTraceState = oldTraceData.inboundTraceState; - this.preserveOtelSpan = true; } public TraceData(TraceData oldTraceData, boolean copyCustomServiceMetadata, String resource) { @@ -61,86 +32,6 @@ public ServiceSpan getServiceSpan() { return serviceSpan; } - public Span getOtelSpan() { - return otelSpan; - } - - public Context getOtelContext() { - return otelContext; - } - - public void setPendingParentContext(Context context) { - this.pendingParentContext = context == null ? Context.root() : context; - } - - public Context consumePendingParentContext() { - Context context = pendingParentContext; - pendingParentContext = Context.root(); - return context; - } - - public void setInboundTraceParent(String traceParent) { - this.inboundTraceParent = traceParent; - } - - public String getInboundTraceParent() { - return inboundTraceParent; - } - - public void setInboundTraceState(String traceState) { - this.inboundTraceState = traceState; - } - - public String getInboundTraceState() { - return inboundTraceState; - } - - public void startNewOtelSpan(String spanName, SpanKind spanKind, Context parentContext) { - closeActiveScope(); - if (otelSpan != null && otelSpan.getSpanContext().isValid()) { - otelSpan.end(); - } - Context context = parentContext != null ? parentContext : Context.root(); - Span span = GlobalOpenTelemetry.getTracer(WOODY) - .spanBuilder(spanName) - .setSpanKind(spanKind) - .setParent(context) - .startSpan(); - this.otelSpan = span; - this.otelContext = context.with(span); - this.ownsOtelSpan = true; - this.preserveOtelSpan = false; - } - - public void openOtelScope() { - closeActiveScope(); - this.activeScope = otelContext.makeCurrent(); - } - - public void finishOtelSpan() { - closeActiveScope(); - if (ownsOtelSpan && otelSpan != null) { - otelSpan.end(); - } - otelSpan = Span.getInvalid(); - otelContext = Context.root(); - ownsOtelSpan = false; - preserveOtelSpan = false; - inboundTraceParent = null; - inboundTraceState = null; - } - - private void closeActiveScope() { - if (activeScope != null) { - activeScope.close(); - activeScope = null; - } - } - - private void adoptOtelContext(Context context) { - this.otelContext = context == null ? Context.root() : context; - } - /** * Checks if {@link ServiceSpan} is filled to determine root: * - request initialized by server: span must be filled by server with data referred from client: @@ -198,29 +89,9 @@ public ContextSpan getSpan(boolean isClient) { public void reset() { clientSpan.reset(); serviceSpan.reset(); - finishOtelSpan(); - setPendingParentContext(Context.root()); - inboundTraceParent = null; - inboundTraceState = null; } public TraceData cloneObject() { return new TraceData(this); } - - public boolean shouldPreserveOtelSpan() { - return preserveOtelSpan && otelSpan != null && otelSpan.getSpanContext().isValid(); - } - - public void clearPreserveOtelSpan() { - this.preserveOtelSpan = false; - } - - private void startPlaceholderSpan() { - this.otelSpan = Span.getInvalid(); - this.otelContext = Context.root(); - this.ownsOtelSpan = false; - this.activeScope = null; - this.preserveOtelSpan = false; - } } diff --git a/woody-api/src/main/java/dev/vality/woody/api/trace/context/TraceContext.java b/woody-api/src/main/java/dev/vality/woody/api/trace/context/TraceContext.java index 34a054ce..0a2eccb6 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/trace/context/TraceContext.java +++ b/woody-api/src/main/java/dev/vality/woody/api/trace/context/TraceContext.java @@ -4,8 +4,6 @@ import dev.vality.woody.api.generator.IdGenerator; import dev.vality.woody.api.trace.Span; import dev.vality.woody.api.trace.TraceData; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.context.Context; import java.util.Optional; @@ -158,7 +156,6 @@ public void init() { traceData = initServiceContext(traceData); } setCurrentTraceData(traceData); - initializeOtelSpan(traceData, clientInit); MDCUtils.putTraceData(traceData, traceData.getActiveSpan()); postInit.run(); @@ -185,7 +182,6 @@ public void destroy(boolean onError) { preDestroy.run(); } } finally { - traceData.finishOtelSpan(); if (isClient) { restored = destroyClientContext(traceData); clearContext = restored == null; @@ -212,30 +208,6 @@ private void setDuration(TraceData traceData, boolean isClient) { span.setDuration(System.currentTimeMillis() - span.getTimestamp()); } - private void initializeOtelSpan(TraceData traceData, boolean clientInit) { - if (traceData.shouldPreserveOtelSpan()) { - traceData.setPendingParentContext(Context.root()); - traceData.openOtelScope(); - traceData.clearPreserveOtelSpan(); - return; - } - - if (clientInit) { - traceData.startNewOtelSpan(TraceData.OTEL_CLIENT, SpanKind.CLIENT, Context.current()); - traceData.setPendingParentContext(Context.root()); - traceData.openOtelScope(); - return; - } - - Context parentContext = traceData.consumePendingParentContext(); - if (parentContext == null) { - parentContext = Context.current(); - } - traceData.startNewOtelSpan(TraceData.OTEL_SERVER, SpanKind.SERVER, parentContext); - traceData.setPendingParentContext(Context.root()); - traceData.openOtelScope(); - } - private TraceData initClientContext(TraceData traceData) { savedTraceData.set(traceData); traceData = createNewTraceData(traceData); diff --git a/woody-api/src/main/java/dev/vality/woody/api/transport/TransportEventInterceptor.java b/woody-api/src/main/java/dev/vality/woody/api/transport/TransportEventInterceptor.java index 997bb6ec..f734ba20 100644 --- a/woody-api/src/main/java/dev/vality/woody/api/transport/TransportEventInterceptor.java +++ b/woody-api/src/main/java/dev/vality/woody/api/transport/TransportEventInterceptor.java @@ -5,8 +5,6 @@ import dev.vality.woody.api.interceptor.CommonInterceptor; import dev.vality.woody.api.trace.MetadataProperties; import dev.vality.woody.api.trace.TraceData; -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.api.trace.StatusCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,10 +30,6 @@ public boolean interceptRequest(TraceData traceData, Object providerContext, Obj LOG.trace("Intercept request transportEvent"); traceData.getActiveSpan().getMetadata().putValue(MetadataProperties.EVENT_TYPE, traceData.isClient() ? ClientEventType.CLIENT_SEND : ServiceEventType.SERVICE_RECEIVE); - traceData.getOtelSpan() - .setStatus(StatusCode.OK) - .addEvent(traceData.isClient() ? ClientEventType.CLIENT_SEND.name() : - ServiceEventType.SERVICE_RECEIVE.name()); reqListener.run(); return true; } @@ -45,10 +39,6 @@ public boolean interceptResponse(TraceData traceData, Object providerContext, Ob LOG.trace("Intercept response transportEvent"); traceData.getActiveSpan().getMetadata().putValue(MetadataProperties.EVENT_TYPE, traceData.isClient() ? ClientEventType.CLIENT_RECEIVE : ServiceEventType.SERVICE_RESULT); - traceData.getOtelSpan() - .setStatus(StatusCode.OK) - .addEvent(traceData.isClient() ? ClientEventType.CLIENT_RECEIVE.name() : - ServiceEventType.SERVICE_RESULT.name()); respListener.run(); return true; } @@ -56,28 +46,16 @@ public boolean interceptResponse(TraceData traceData, Object providerContext, Ob @Override public boolean interceptError(TraceData traceData, Throwable t, boolean isClient) { LOG.trace("Intercept error transportEvent"); - Span span = traceData.getOtelSpan(); Object lastEvent = traceData.getActiveSpan().getMetadata().getValue(MetadataProperties.EVENT_TYPE); if (isClient && !ClientEventType.CLIENT_RECEIVE.equals(lastEvent)) { traceData.getActiveSpan().getMetadata().putValue(MetadataProperties.EVENT_TYPE, ClientEventType.CLIENT_RECEIVE); - if (span.getSpanContext().isValid()) { - span.addEvent(ClientEventType.CLIENT_RECEIVE.name()); - } respListener.run(); } else if (!isClient && !ServiceEventType.SERVICE_RESULT.equals(lastEvent)) { traceData.getActiveSpan().getMetadata().putValue(MetadataProperties.EVENT_TYPE, ServiceEventType.SERVICE_RESULT); - if (span.getSpanContext().isValid()) { - span.addEvent(ServiceEventType.SERVICE_RESULT.name()); - } respListener.run(); } - if (span.getSpanContext().isValid()) { - span.recordException(t); - span.setStatus(StatusCode.ERROR); - span.addEvent("ERROR"); - } errListener.run(); return (CommonInterceptor.super.interceptError(traceData, t, isClient)); } diff --git a/woody-api/src/test/java/dev/vality/woody/api/MdcUtilsExtendedTest.java b/woody-api/src/test/java/dev/vality/woody/api/MdcUtilsExtendedTest.java index dd1f5756..5c143d81 100644 --- a/woody-api/src/test/java/dev/vality/woody/api/MdcUtilsExtendedTest.java +++ b/woody-api/src/test/java/dev/vality/woody/api/MdcUtilsExtendedTest.java @@ -61,7 +61,6 @@ public void testExtendedFieldsPopulated() throws Exception { assertEquals("client-request-1", MDC.get("rpc.client.metadata.user-identity.x-request-id")); assertEquals("client-deadline-iso", MDC.get("rpc.client.metadata.user-identity.x-request-deadline")); - traceData.getOtelSpan().end(); } @Test @@ -75,7 +74,6 @@ public void testDisableExtendedFields() throws Exception { assertNull(MDC.get("rpc.client.service")); assertNull(MDC.get("rpc.client.metadata.user-identity.x-request-id")); - traceData.getOtelSpan().end(); } private TraceData buildTraceData() throws Exception { diff --git a/woody-api/src/test/java/dev/vality/woody/api/flow/concurrent/TestMDCInConcurent.java b/woody-api/src/test/java/dev/vality/woody/api/flow/concurrent/TestMDCInConcurent.java index 39cdc328..25b74216 100644 --- a/woody-api/src/test/java/dev/vality/woody/api/flow/concurrent/TestMDCInConcurent.java +++ b/woody-api/src/test/java/dev/vality/woody/api/flow/concurrent/TestMDCInConcurent.java @@ -4,7 +4,6 @@ import dev.vality.woody.api.trace.Span; import dev.vality.woody.api.trace.TraceData; import dev.vality.woody.api.trace.context.TraceContext; -import io.opentelemetry.api.trace.SpanContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -26,15 +25,10 @@ public class TestMDCInConcurent { Runnable runnable = () -> { try { Span span = TraceContext.getCurrentTraceData().getActiveSpan().getSpan(); - io.opentelemetry.api.trace.Span otelSpan = TraceContext.getCurrentTraceData().getOtelSpan(); - SpanContext spanContext = otelSpan.getSpanContext(); - log.info("Runnable {} {} {} {} {}", span.getId(), span.getParentId(), span.getTraceId(), - spanContext.getSpanId(), spanContext.getTraceId()); + log.info("Runnable {} {} {}", span.getId(), span.getParentId(), span.getTraceId()); assertEquals(MDC.get(MDCUtils.SPAN_ID), span.getId()); assertEquals(MDC.get(MDCUtils.TRACE_ID), span.getTraceId()); assertEquals(MDC.get(MDCUtils.PARENT_ID), span.getParentId()); - assertEquals(MDC.get(MDCUtils.OTEL_SPAN_ID), spanContext.getSpanId()); - assertEquals(MDC.get(MDCUtils.OTEL_TRACE_ID), spanContext.getTraceId()); } catch (Throwable t) { log.error("Error: ", t); } @@ -42,15 +36,10 @@ public class TestMDCInConcurent { Callable callable = () -> { try { Span span = TraceContext.getCurrentTraceData().getActiveSpan().getSpan(); - io.opentelemetry.api.trace.Span otelSpan = TraceContext.getCurrentTraceData().getOtelSpan(); - SpanContext spanContext = otelSpan.getSpanContext(); - log.info("Callable {} {} {} {} {}", span.getId(), span.getParentId(), span.getTraceId(), - spanContext.getSpanId(), spanContext.getTraceId()); + log.info("Callable {} {} {}", span.getId(), span.getParentId(), span.getTraceId()); assertEquals(MDC.get(MDCUtils.SPAN_ID), span.getId()); assertEquals(MDC.get(MDCUtils.TRACE_ID), span.getTraceId()); assertEquals(MDC.get(MDCUtils.PARENT_ID), span.getParentId()); - assertEquals(MDC.get(MDCUtils.OTEL_TRACE_ID), spanContext.getTraceId()); - assertEquals(MDC.get(MDCUtils.OTEL_SPAN_ID), spanContext.getSpanId()); } catch (Throwable t) { log.error("Error: ", t); } diff --git a/woody-api/src/test/java/dev/vality/woody/api/interceptor/ContextInterceptorTest.java b/woody-api/src/test/java/dev/vality/woody/api/interceptor/ContextInterceptorTest.java index 8484ad60..02f108c1 100644 --- a/woody-api/src/test/java/dev/vality/woody/api/interceptor/ContextInterceptorTest.java +++ b/woody-api/src/test/java/dev/vality/woody/api/interceptor/ContextInterceptorTest.java @@ -26,9 +26,6 @@ public void setUp() { @After public void tearDown() { MDC.clear(); - if (testTraceData != null) { - testTraceData.getOtelSpan().end(); - } TraceContext.setCurrentTraceData(originalTraceData); } diff --git a/woody-thrift/pom.xml b/woody-thrift/pom.xml index 28dd8f19..10bd7cd2 100644 --- a/woody-thrift/pom.xml +++ b/woody-thrift/pom.xml @@ -94,10 +94,6 @@ httpclient5 5.5.1 - - io.opentelemetry.semconv - opentelemetry-semconv - org.easymock easymock diff --git a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/THSpawnClientBuilder.java b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/THSpawnClientBuilder.java index 5639049a..07efc093 100644 --- a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/THSpawnClientBuilder.java +++ b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/THSpawnClientBuilder.java @@ -7,7 +7,6 @@ import dev.vality.woody.api.proxy.InvocationTargetProvider; import dev.vality.woody.api.proxy.SpawnTargetProvider; import dev.vality.woody.api.trace.context.metadata.MetadataExtensionKit; -import io.opentelemetry.sdk.resources.Resource; import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager; diff --git a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/TraceParentUtils.java b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/TraceParentUtils.java deleted file mode 100644 index 97ca6a20..00000000 --- a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/TraceParentUtils.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.vality.woody.thrift.impl.http; - -public class TraceParentUtils { - - public static String DEFAULT_VERSION = "00"; - - public static String initParentTrace(String version, String trace, String span, String flag) { - return version + "-" + trace + "-" + span + "-" + flag; - } - - public static String parseVersion(String parentTraceId) { - return parentTraceId.split("-").length > 0 ? parentTraceId.split("-")[0] : ""; - } - - public static String parseTraceId(String parentTraceId) { - return parentTraceId.split("-").length > 1 ? parentTraceId.split("-")[1] : ""; - } - - public static String parseSpanId(String parentTraceId) { - return parentTraceId.split("-").length > 2 ? parentTraceId.split("-")[2] : ""; - } - - public static String parseFlag(String parentTraceId) { - return parentTraceId.split("-").length > 3 ? parentTraceId.split("-")[3] : ""; - } - -} diff --git a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/interceptor/ext/TransportExtensionBundles.java b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/interceptor/ext/TransportExtensionBundles.java index dedf74e4..ffd69c1d 100644 --- a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/interceptor/ext/TransportExtensionBundles.java +++ b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/interceptor/ext/TransportExtensionBundles.java @@ -12,13 +12,6 @@ import dev.vality.woody.thrift.impl.http.transport.THttpHeader; import dev.vality.woody.thrift.impl.http.transport.TTransportErrorType; import dev.vality.woody.thrift.impl.http.transport.UrlStringEndpoint; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.context.Context; -import io.opentelemetry.context.propagation.TextMapGetter; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.context.propagation.TextMapSetter; -import io.opentelemetry.semconv.HttpAttributes; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; @@ -141,11 +134,8 @@ private static String resolveClientEndpoint(THCExtensionContext reqCCtx) { reqCCtx.setRequestHeader(THttpHeader.TRACE_ID.getKey(), span.getTraceId()); reqCCtx.setRequestHeader(THttpHeader.SPAN_ID.getKey(), span.getId()); reqCCtx.setRequestHeader(THttpHeader.PARENT_ID.getKey(), span.getParentId()); - injectTraceHeaders(reqCCtx); }, (InterceptorExtension) respCCtx -> { - applyResponseStatus(respCCtx.getTraceData(), respCCtx.getResponseStatus()); }), createCtxBundle((InterceptorExtension) reqSCtx -> { - extractTraceContext(reqSCtx); HttpServletRequest request = reqSCtx.getProviderRequest(); Span span = reqSCtx.getTraceData().getServiceSpan().getSpan(); List>> headerConsumers = @@ -160,8 +150,6 @@ private static String resolveClientEndpoint(THCExtensionContext reqCCtx) { respSCtx.setResponseHeader(THttpHeader.TRACE_ID.getKey(), span.getTraceId()); respSCtx.setResponseHeader(THttpHeader.PARENT_ID.getKey(), span.getParentId()); respSCtx.setResponseHeader(THttpHeader.SPAN_ID.getKey(), span.getId()); - injectTraceHeaders(respSCtx); - applyResponseStatus(respSCtx.getTraceData(), respSCtx.getProviderResponse().getStatus()); })); public static final ExtensionBundle TRANSPORT_STATE_MAPPING_BUNDLE = createExtBundle(createCtxBundle( @@ -207,7 +195,6 @@ private static String resolveClientEndpoint(THCExtensionContext reqCCtx) { response.setHeader(THttpHeader.ERROR_REASON.getKey(), val); }); serviceSpan.getMetadata().putValue(THMetadataProperties.TH_TRANSPORT_RESPONSE_SET_FLAG, true); - applyResponseStatus(respSCtx.getTraceData(), responseInfo.getStatus()); } })); @@ -219,31 +206,6 @@ private static String resolveClientEndpoint(THCExtensionContext reqCCtx) { Arrays.asList(TRANSPORT_CONFIG_BUNDLE, RPC_ID_BUNDLE, CALL_ENDPOINT_BUNDLE, TRANSPORT_STATE_MAPPING_BUNDLE, TRANSPORT_INJECTION_BUNDLE, DEADLINE_BUNDLE)); - private static final TextMapGetter REQUEST_HEADER_GETTER = new TextMapGetter<>() { - @Override - public Iterable keys(HttpServletRequest carrier) { - if (carrier == null) { - return Collections.emptyList(); - } - Enumeration headerNames = carrier.getHeaderNames(); - return headerNames == null ? Collections.emptyList() : Collections.list(headerNames); - } - - @Override - public String get(HttpServletRequest carrier, String key) { - if (carrier == null || key == null) { - return null; - } - return carrier.getHeader(key); - } - }; - - private static final TextMapSetter CLIENT_REQUEST_SETTER = (carrier, key, value) -> { - if (carrier != null && key != null && value != null) { - carrier.setRequestHeader(key, value); - } - }; - public static List getClientExtensions() { return clientList; } @@ -256,50 +218,6 @@ public static List getExtensions(boolean isClient) { return isClient ? getClientExtensions() : getServiceExtensions(); } - private static TextMapPropagator propagator() { - return GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator(); - } - - private static void extractTraceContext(THSExtensionContext context) { - HttpServletRequest request = context.getProviderRequest(); - Context extracted = propagator().extract(Context.root(), request, REQUEST_HEADER_GETTER); - if (io.opentelemetry.api.trace.Span.fromContext(extracted).getSpanContext().isValid()) { - context.getTraceData().setInboundTraceParent(request.getHeader(THttpHeader.TRACE_PARENT.getKey())); - context.getTraceData().setInboundTraceState(request.getHeader(THttpHeader.TRACE_STATE.getKey())); - } else { - context.getTraceData().setInboundTraceParent(null); - context.getTraceData().setInboundTraceState(null); - } - context.getTraceData().setPendingParentContext(extracted); - } - - private static void injectTraceHeaders(THCExtensionContext context) { - propagator().inject(context.getTraceData().getOtelContext(), context, CLIENT_REQUEST_SETTER); - } - - private static void injectTraceHeaders(THSExtensionContext context) { - String traceParent = context.getTraceData().getInboundTraceParent(); - if (traceParent != null && !traceParent.isEmpty()) { - context.setResponseHeader(THttpHeader.TRACE_PARENT.getKey(), traceParent); - String traceState = context.getTraceData().getInboundTraceState(); - if (traceState != null && !traceState.isEmpty()) { - context.setResponseHeader(THttpHeader.TRACE_STATE.getKey(), traceState); - } - } - } - - private static void applyResponseStatus(TraceData traceData, int status) { - if (status <= 0) { - return; - } - io.opentelemetry.api.trace.Span span = traceData.getOtelSpan(); - if (span == null || !span.getSpanContext().isValid()) { - return; - } - span.setAttribute(HttpAttributes.HTTP_RESPONSE_STATUS_CODE, status); - span.setStatus(status >= 500 ? StatusCode.ERROR : StatusCode.OK); - } - private static void logIfError(ContextSpan contextSpan) { Throwable t = ContextUtils.getCallError(contextSpan); if (t != null) { diff --git a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/transport/THttpHeader.java b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/transport/THttpHeader.java index a3e378fd..e62dc1d3 100644 --- a/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/transport/THttpHeader.java +++ b/woody-thrift/src/main/java/dev/vality/woody/thrift/impl/http/transport/THttpHeader.java @@ -3,8 +3,6 @@ public enum THttpHeader { TRACE_ID("woody.trace-id", false), SPAN_ID("woody.span-id", false), - TRACE_PARENT("traceparent", true), - TRACE_STATE("tracestate", true), PARENT_ID("woody.parent-id", false), DEADLINE("woody.deadline", false), ERROR_CLASS("woody.error-class", false), diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/AbstractTest.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/AbstractTest.java index d24dd893..62e6f38f 100644 --- a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/AbstractTest.java +++ b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/AbstractTest.java @@ -5,11 +5,6 @@ import dev.vality.woody.api.generator.IdGenerator; import dev.vality.woody.api.trace.context.metadata.MetadataExtensionKit; import dev.vality.woody.rpc.OwnerServiceSrv; -import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.samplers.Sampler; import jakarta.servlet.Servlet; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; @@ -45,13 +40,6 @@ public class AbstractTest { protected TProcessor tProcessor; private HandlerCollection handlerCollection; - static { - OpenTelemetrySdk.builder() - .setTracerProvider(SdkTracerProvider.builder().setSampler(Sampler.alwaysOn()).build()) - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) - .buildAndRegisterGlobal(); - } - @Before public void startJetty() throws Exception { diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MDCLogTest.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MDCLogTest.java index feab367e..00955492 100644 --- a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MDCLogTest.java +++ b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MDCLogTest.java @@ -12,7 +12,6 @@ import dev.vality.woody.api.generator.TimestampIdGenerator; import dev.vality.woody.thrift.impl.http.event.THClientEvent; import dev.vality.woody.thrift.impl.http.event.THServiceEvent; -import io.opentelemetry.api.trace.SpanContext; import org.apache.thrift.TException; import org.junit.Assert; import org.junit.Before; @@ -37,34 +36,20 @@ public class MDCLogTest extends AbstractTest { assertNotNull(MDC.get(MDCUtils.SPAN_ID)); assertNotNull(MDC.get(MDCUtils.TRACE_ID)); assertNotNull(MDC.get(MDCUtils.PARENT_ID)); - assertNotNull(MDC.get(MDCUtils.OTEL_SPAN_ID)); - assertNotNull(MDC.get(MDCUtils.OTEL_TRACE_ID)); - assertNotNull(MDC.get(MDCUtils.OTEL_TRACE_FLAGS)); assertEquals(MDC.get(MDCUtils.SPAN_ID), event.getSpanId()); assertEquals(MDC.get(MDCUtils.TRACE_ID), event.getTraceId()); assertEquals(MDC.get(MDCUtils.PARENT_ID), event.getParentId()); - SpanContext spanContext = event.getTraceData().getOtelSpan().getSpanContext(); - assertEquals(MDC.get(MDCUtils.OTEL_SPAN_ID), spanContext.getSpanId()); - assertEquals(MDC.get(MDCUtils.OTEL_TRACE_ID), spanContext.getTraceId()); - assertEquals(MDC.get(MDCUtils.OTEL_TRACE_FLAGS), spanContext.getTraceFlags().asHex()); }; ServiceEventListener serviceEventListener = (ServiceEventListener) event -> { assertNotNull(MDC.get(MDCUtils.SPAN_ID)); assertNotNull(MDC.get(MDCUtils.TRACE_ID)); assertNotNull(MDC.get(MDCUtils.PARENT_ID)); - assertNotNull(MDC.get(MDCUtils.OTEL_SPAN_ID)); - assertNotNull(MDC.get(MDCUtils.OTEL_TRACE_FLAGS)); - assertNotNull(MDC.get(MDCUtils.OTEL_TRACE_ID)); assertEquals(MDC.get(MDCUtils.SPAN_ID), event.getSpanId()); assertEquals(MDC.get(MDCUtils.TRACE_ID), event.getTraceId()); assertEquals(MDC.get(MDCUtils.PARENT_ID), event.getParentId()); - SpanContext spanContext = event.getTraceData().getOtelSpan().getSpanContext(); - assertEquals(MDC.get(MDCUtils.OTEL_SPAN_ID), spanContext.getSpanId()); - assertEquals(MDC.get(MDCUtils.OTEL_TRACE_ID), spanContext.getTraceId()); - assertEquals(MDC.get(MDCUtils.OTEL_TRACE_FLAGS), spanContext.getTraceFlags().asHex()); }; OwnerServiceSrv.Iface client1 = createThriftRPCClient(OwnerServiceSrv.Iface.class, new TimestampIdGenerator(), diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java deleted file mode 100644 index e83b05d1..00000000 --- a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java +++ /dev/null @@ -1,277 +0,0 @@ -package dev.vality.woody.thrift.impl.http; - -import dev.vality.woody.api.MDCUtils; -import dev.vality.woody.api.event.ClientEventListener; -import dev.vality.woody.api.event.ClientEventType; -import dev.vality.woody.api.event.ServiceEventListener; -import dev.vality.woody.api.generator.TimestampIdGenerator; -import dev.vality.woody.api.trace.ContextUtils; -import dev.vality.woody.api.trace.context.TraceContext; -import dev.vality.woody.api.trace.context.metadata.MetadataExtensionKit; -import dev.vality.woody.rpc.Owner; -import dev.vality.woody.rpc.OwnerServiceSrv; -import dev.vality.woody.thrift.impl.http.event.THClientEvent; -import jakarta.servlet.Servlet; -import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.core5.http.EntityDetails; -import org.apache.hc.core5.http.HttpException; -import org.apache.hc.core5.http.HttpRequest; -import org.apache.hc.core5.http.protocol.HttpContext; -import org.apache.thrift.TException; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.MDC; - -import java.io.IOException; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -import static org.junit.Assert.*; - -public class MetadataMdcPropagationTest extends AbstractTest { - - private static final String X_REQUEST_ID = "068e67b4-74bc-4333-9c14-090e6acc3227"; - private static final String X_REQUEST_DEADLINE = "2025-01-01T12:30:00Z"; - private static final String TRACE_ID = "4e0e9f8d8d8044f9b65a3b0f5cdfc2d1"; - private static final String SPAN_ID = "1a2b3c4d5e6f7081"; - private static final String TRACE_STATE = "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE"; - - private final AtomicReference upstreamMetadataId = new AtomicReference<>(); - private final AtomicReference upstreamMetadataDeadline = new AtomicReference<>(); - private final AtomicReference upstreamMdcId = new AtomicReference<>(); - private final AtomicReference upstreamMdcDeadline = new AtomicReference<>(); - private final AtomicReference downstreamMetadataId = new AtomicReference<>(); - private final AtomicReference downstreamMetadataDeadline = new AtomicReference<>(); - private final AtomicReference downstreamMdcId = new AtomicReference<>(); - private final AtomicReference downstreamMdcDeadline = new AtomicReference<>(); - private final AtomicReference downstreamRpcServerService = new AtomicReference<>(); - private final AtomicReference downstreamRpcServerFunction = new AtomicReference<>(); - private final AtomicReference downstreamRpcServerUrl = new AtomicReference<>(); - private final AtomicReference upstreamOtelTraceId = new AtomicReference<>(); - private final AtomicReference downstreamOtelTraceId = new AtomicReference<>(); - private final AtomicReference upstreamTraceState = new AtomicReference<>(); - private final AtomicReference downstreamTraceState = new AtomicReference<>(); - private final AtomicReference upstreamTraceParent = new AtomicReference<>(); - private final AtomicReference downstreamTraceParent = new AtomicReference<>(); - private final AtomicReference responseTraceParent = new AtomicReference<>(); - private final AtomicReference responseTraceState = new AtomicReference<>(); - private final AtomicReference upstreamRpcServerService = new AtomicReference<>(); - private final AtomicReference upstreamRpcServerFunction = new AtomicReference<>(); - private final AtomicReference upstreamRpcServerUrl = new AtomicReference<>(); - private final AtomicReference upstreamRpcClientService = new AtomicReference<>(); - private final AtomicReference upstreamRpcClientFunction = new AtomicReference<>(); - private final AtomicReference upstreamRpcClientUrl = new AtomicReference<>(); - private final AtomicReference upstreamClientPrefixAfterCall = new AtomicReference<>(); - - private OwnerServiceSrv.Iface downstreamClient; - - @Override - protected Servlet createThriftRPCService(Class iface, T handler, - ServiceEventListener eventListener, - List extensionKits) { - THServiceBuilder serviceBuilder = new THServiceBuilder(); - serviceBuilder.withLogEnabled(false); - if (eventListener != null) { - serviceBuilder.withEventListener(eventListener); - } - serviceBuilder.withMetaExtensions(extensionKits); - return serviceBuilder.build(iface, handler); - } - - @Before - public void setUpServices() throws Exception { - OwnerServiceSrv.Iface downstreamHandler = new OwnerServiceStub() { - @Override - public Owner getOwner(int id) throws TException { - downstreamMetadataId.set(ContextUtils.getCustomMetadataValue(String.class, - "user-identity.x-request-id")); - downstreamMetadataDeadline.set(ContextUtils.getCustomMetadataValue(String.class, - "user-identity.x-request-deadline")); - downstreamMdcId.set(MDC.get("rpc.server.metadata.user-identity.x-request-id")); - downstreamMdcDeadline.set(MDC.get("rpc.server.metadata.user-identity.x-request-deadline")); - downstreamOtelTraceId.set( - TraceContext.getCurrentTraceData().getOtelSpan().getSpanContext().getTraceId()); - downstreamTraceState.set(TraceContext.getCurrentTraceData().getInboundTraceState()); - downstreamTraceParent.set(TraceContext.getCurrentTraceData().getInboundTraceParent()); - downstreamRpcServerService.set(MDC.get("rpc.server.service")); - downstreamRpcServerFunction.set(MDC.get("rpc.server.function")); - downstreamRpcServerUrl.set(MDC.get("rpc.server.url")); - return new Owner(id, "downstream"); - } - }; - - Servlet downstreamServlet = createThriftRPCService(OwnerServiceSrv.Iface.class, downstreamHandler); - - OwnerServiceSrv.Iface upstreamHandler = new OwnerServiceStub() { - @Override - public Owner getOwner(int id) throws TException { - upstreamMetadataId.set(ContextUtils.getCustomMetadataValue(String.class, - "user-identity.x-request-id")); - upstreamMetadataDeadline.set(ContextUtils.getCustomMetadataValue(String.class, - "user-identity.x-request-deadline")); - upstreamMdcId.set(MDC.get("rpc.server.metadata.user-identity.x-request-id")); - upstreamMdcDeadline.set(MDC.get("rpc.server.metadata.user-identity.x-request-deadline")); - upstreamOtelTraceId.set( - TraceContext.getCurrentTraceData().getOtelSpan().getSpanContext().getTraceId()); - upstreamTraceState.set(TraceContext.getCurrentTraceData().getInboundTraceState()); - upstreamTraceParent.set(TraceContext.getCurrentTraceData().getInboundTraceParent()); - upstreamRpcServerService.set(MDC.get("rpc.server.service")); - upstreamRpcServerFunction.set(MDC.get("rpc.server.function")); - upstreamRpcServerUrl.set(MDC.get("rpc.server.url")); - - Owner result = downstreamClient.getOwner(id); - - upstreamClientPrefixAfterCall.set(MDC.get("rpc.client.service")); - assertNotNull("Active trace context must be available", TraceContext.getCurrentTraceData()); - return result; - } - }; - - Servlet upstreamServlet = createThriftRPCService(OwnerServiceSrv.Iface.class, upstreamHandler); - - org.eclipse.jetty.servlet.ServletContextHandler context = new org.eclipse.jetty.servlet.ServletContextHandler(); - context.setContextPath("/"); - context.addServlet(new org.eclipse.jetty.servlet.ServletHolder("downstream", downstreamServlet), - "/downstream"); - context.addServlet(new org.eclipse.jetty.servlet.ServletHolder("upstream", upstreamServlet), - "/upstream"); - ((org.eclipse.jetty.server.handler.HandlerCollection) server.getHandler()).addHandler(context); - context.start(); - - ClientEventListener clientEventListener = new ClientEventListener() { - @Override - public void notifyEvent(THClientEvent event) { - if (ClientEventType.CLIENT_SEND.equals(event.getEventType())) { - upstreamRpcClientService.set(MDC.get(MDCUtils.TRACE_RPC_CLIENT_PREFIX + "service")); - upstreamRpcClientFunction.set(MDC.get(MDCUtils.TRACE_RPC_CLIENT_PREFIX + "function")); - upstreamRpcClientUrl.set(MDC.get(MDCUtils.TRACE_RPC_CLIENT_PREFIX + "url")); - } - } - }; - - downstreamClient = createThriftRPCClient(OwnerServiceSrv.Iface.class, new TimestampIdGenerator(), - clientEventListener, null, getUrlString("/downstream")); - } - - @Test - public void shouldPropagateMetadataHeadersAndPopulateMdc() throws Exception { - clearCapturedValues(); - - try (CloseableHttpClient httpClient = HttpClients.custom() - .addRequestInterceptorLast(this::injectHeaders) - .addResponseInterceptorLast(this::captureResponseHeaders) - .build()) { - OwnerServiceSrv.Iface entryClient = createThriftRPCClient(OwnerServiceSrv.Iface.class, - new TimestampIdGenerator(), null, null, getUrlString("/upstream"), networkTimeout, httpClient); - - entryClient.getOwner(42); - } - - assertEquals(X_REQUEST_ID, upstreamMetadataId.get()); - assertEquals(X_REQUEST_DEADLINE, upstreamMetadataDeadline.get()); - assertEquals(X_REQUEST_ID, upstreamMdcId.get()); - assertEquals(X_REQUEST_DEADLINE, upstreamMdcDeadline.get()); - - assertEquals(X_REQUEST_ID, downstreamMetadataId.get()); - assertEquals(X_REQUEST_DEADLINE, downstreamMetadataDeadline.get()); - assertEquals(X_REQUEST_ID, downstreamMdcId.get()); - assertEquals(X_REQUEST_DEADLINE, downstreamMdcDeadline.get()); - assertEquals("OwnerService", downstreamRpcServerService.get()); - assertEquals("getOwner", downstreamRpcServerFunction.get()); - assertTrue("Server URL should contain downstream path", - downstreamRpcServerUrl.get() != null && downstreamRpcServerUrl.get().contains("/downstream")); - String upstreamTraceId = upstreamOtelTraceId.get(); - String downstreamTraceId = downstreamOtelTraceId.get(); - assertNotNull(upstreamTraceId); - assertNotNull(downstreamTraceId); - assertEquals(upstreamTraceId, downstreamTraceId); - assertEquals(32, upstreamTraceId.length()); - assertNotEquals("00000000000000000000000000000000", upstreamTraceId); - assertEquals(TRACE_STATE, upstreamTraceState.get()); - assertEquals(TRACE_STATE, downstreamTraceState.get()); - assertNotNull("Upstream traceparent must be captured", upstreamTraceParent.get()); - assertNotNull("Downstream traceparent must be captured", downstreamTraceParent.get()); - assertNotNull("traceparent in HTTP response must be present", responseTraceParent.get()); - assertTrue("Upstream traceparent should contain the original trace ID", - upstreamTraceParent.get().contains(TRACE_ID)); - assertTrue("Downstream traceparent should contain the original trace ID", - downstreamTraceParent.get().contains(TRACE_ID)); - assertTrue("Response traceparent should contain the original trace ID", - responseTraceParent.get().contains(TRACE_ID)); - assertEquals(TRACE_STATE, responseTraceState.get()); - assertEquals("OwnerService", upstreamRpcServerService.get()); - assertEquals("getOwner", upstreamRpcServerFunction.get()); - assertTrue("Server URL should contain upstream path", - upstreamRpcServerUrl.get() != null && upstreamRpcServerUrl.get().contains("/upstream")); - assertEquals("OwnerService", upstreamRpcClientService.get()); - assertEquals("getOwner", upstreamRpcClientFunction.get()); - assertEquals(getUrlString("/downstream"), upstreamRpcClientUrl.get()); - assertEquals("OwnerService", upstreamClientPrefixAfterCall.get()); - } - - private void injectHeaders(HttpRequest request, EntityDetails entity, HttpContext context) - throws HttpException, IOException { - if (entity != null) { - entity.getContentLength(); - } - if (context != null) { - context.hashCode(); - } - request.setHeader("woody.meta.user-identity.x-request-id", X_REQUEST_ID); - request.setHeader("woody.meta.user-identity.x-request-deadline", X_REQUEST_DEADLINE); - request.setHeader("woody.trace-id", TRACE_ID); - request.setHeader("woody.span-id", SPAN_ID); - request.setHeader("woody.parent-id", TraceContext.NO_PARENT_ID); - request.setHeader("traceparent", String.format("00-%s-%s-01", TRACE_ID, SPAN_ID)); - request.setHeader("tracestate", TRACE_STATE); - } - - private void captureResponseHeaders(org.apache.hc.core5.http.HttpResponse response, - EntityDetails entityDetails, - HttpContext context) throws HttpException, IOException { - if (entityDetails != null) { - entityDetails.getContentType(); - } - if (context != null) { - context.hashCode(); - } - var traceParentHeader = response.getFirstHeader("traceparent"); - if (traceParentHeader != null) { - responseTraceParent.set(traceParentHeader.getValue()); - } - var traceStateHeader = response.getFirstHeader("tracestate"); - if (traceStateHeader != null) { - responseTraceState.set(traceStateHeader.getValue()); - } - } - - private void clearCapturedValues() { - upstreamMetadataId.set(null); - upstreamMetadataDeadline.set(null); - upstreamMdcId.set(null); - upstreamMdcDeadline.set(null); - downstreamMetadataId.set(null); - downstreamMetadataDeadline.set(null); - downstreamMdcId.set(null); - downstreamMdcDeadline.set(null); - downstreamRpcServerService.set(null); - downstreamRpcServerFunction.set(null); - downstreamRpcServerUrl.set(null); - upstreamOtelTraceId.set(null); - downstreamOtelTraceId.set(null); - upstreamTraceState.set(null); - downstreamTraceState.set(null); - upstreamTraceParent.set(null); - downstreamTraceParent.set(null); - responseTraceParent.set(null); - responseTraceState.set(null); - upstreamRpcServerService.set(null); - upstreamRpcServerFunction.set(null); - upstreamRpcServerUrl.set(null); - upstreamRpcClientService.set(null); - upstreamRpcClientFunction.set(null); - upstreamRpcClientUrl.set(null); - upstreamClientPrefixAfterCall.set(null); - } -} diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TestClientAndServerHttpHeaders.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TestClientAndServerHttpHeaders.java index 12bf5ee0..afede99d 100644 --- a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TestClientAndServerHttpHeaders.java +++ b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TestClientAndServerHttpHeaders.java @@ -183,67 +183,4 @@ public void testWhenTraceDataIsEmpty() throws TException { } } - @Test - public void testTraceDataOtel() throws TException { - addServlet(testServlet, servletContextPath); - CloseableHttpClient httpClient = - HttpClients.custom().addRequestInterceptorLast((httpRequest, entityDetails, httpContext) -> - httpRequest.setHeader( - THttpHeader.TRACE_PARENT.getKey(), - "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01" - ) - ) - .addResponseInterceptorLast((httpResponse, entityDetails, httpContext) -> - assertEquals( - "00-80e1afed08e019fc1110464cfa66635c-7a085853722dc6d2-01", - httpResponse.getHeader(THttpHeader.TRACE_PARENT.getKey()).getValue() - ) - ) - .build(); - - OwnerServiceSrv.Iface client = createThriftRPCClient( - OwnerServiceSrv.Iface.class, getUrlString(servletContextPath), httpClient - ); - client.getIntValue(); - } - - @Test - public void testWhenTraceDataOtelIsEmpty() throws TException { - addServlet(testServlet, servletContextPath); - CloseableHttpClient httpClient = - HttpClients.custom().addRequestInterceptorLast((httpRequest, entityDetails, httpContext) -> - assertNotNull(httpRequest.getHeader(THttpHeader.TRACE_PARENT.getKey())) - ) - .addResponseInterceptorLast((httpResponse, entityDetails, httpContext) -> - assertNotNull(httpResponse.getHeader(THttpHeader.TRACE_PARENT.getKey())) - ) - .build(); - - OwnerServiceSrv.Iface client = createThriftRPCClient( - OwnerServiceSrv.Iface.class, getUrlString(servletContextPath), httpClient - ); - client.getIntValue(); - } - - @Test - public void testWhenTraceDataOtelIsInvalid() throws TException { - addServlet(testServlet, servletContextPath); - CloseableHttpClient httpClient = - HttpClients.custom().addRequestInterceptorLast((httpRequest, entityDetails, httpContext) -> - httpRequest.setHeader( - THttpHeader.TRACE_PARENT.getKey(), - "invalid" - ) - ) - .addResponseInterceptorLast((httpResponse, entityDetails, httpContext) -> - assertNull(httpResponse.getHeader(THttpHeader.TRACE_PARENT.getKey())) - ) - .build(); - - OwnerServiceSrv.Iface client = createThriftRPCClient( - OwnerServiceSrv.Iface.class, getUrlString(servletContextPath), httpClient - ); - client.getIntValue(); - } - } diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TraceLifecycleIntegrationTest.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TraceLifecycleIntegrationTest.java deleted file mode 100644 index 8f215bcb..00000000 --- a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/TraceLifecycleIntegrationTest.java +++ /dev/null @@ -1,607 +0,0 @@ -package dev.vality.woody.thrift.impl.http; - -import dev.vality.woody.api.generator.TimestampIdGenerator; -import dev.vality.woody.api.trace.ContextSpan; -import dev.vality.woody.api.trace.ContextUtils; -import dev.vality.woody.api.trace.TraceData; -import dev.vality.woody.api.trace.context.TraceContext; -import dev.vality.woody.rpc.Owner; -import dev.vality.woody.rpc.OwnerServiceSrv; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.trace.SpanContext; -import io.opentelemetry.api.trace.SpanId; -import io.opentelemetry.api.trace.SpanKind; -import io.opentelemetry.api.trace.StatusCode; -import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.data.SpanData; -import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import jakarta.servlet.Servlet; -import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; -import org.apache.hc.client5.http.impl.classic.HttpClients; -import org.apache.hc.core5.http.EntityDetails; -import org.apache.hc.core5.http.HttpException; -import org.apache.hc.core5.http.HttpRequest; -import org.apache.hc.core5.http.HttpResponse; -import org.apache.hc.core5.http.protocol.HttpContext; -import org.apache.thrift.TException; -import org.eclipse.jetty.server.handler.HandlerCollection; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.slf4j.MDC; - -import java.io.IOException; -import java.time.Instant; -import java.util.Collection; -import java.util.List; -import java.util.Arrays; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; - -import static org.junit.Assert.*; - -public class TraceLifecycleIntegrationTest extends AbstractTest { - - private static final String REQUEST_ID_KEY = "user-identity.x-request-id"; - private static final String DEADLINE_KEY = "user-identity.x-request-deadline"; - private static final String TRACE_PARENT_HEADER = "traceparent"; - private static final String TRACE_STATE_HEADER = "tracestate"; - private static final RecordingSpanExporter SPAN_EXPORTER = new RecordingSpanExporter(); - private static SdkTracerProvider sdkTracerProvider; - - private final AtomicReference scenario = new AtomicReference<>(); - private final AtomicReference upstreamInitial = new AtomicReference<>(); - private final AtomicReference upstreamAfterCall = new AtomicReference<>(); - private final AtomicReference downstreamSnapshot = new AtomicReference<>(); - private final AtomicReference responseTraceParent = new AtomicReference<>(); - private final AtomicReference responseTraceState = new AtomicReference<>(); - - private OwnerServiceSrv.Iface downstreamClient; - - @BeforeClass - public static void configureOpenTelemetry() { - GlobalOpenTelemetry.resetForTest(); - SPAN_EXPORTER.reset(); - sdkTracerProvider = SdkTracerProvider.builder() - .addSpanProcessor(SimpleSpanProcessor.create(SPAN_EXPORTER)) - .build(); - OpenTelemetrySdk.builder() - .setTracerProvider(sdkTracerProvider) - .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance())) - .buildAndRegisterGlobal(); - } - - @Before - public void setUpServices() throws Exception { - scenario.set(ScenarioSettings.fresh("noop")); - SPAN_EXPORTER.reset(); - upstreamInitial.set(null); - upstreamAfterCall.set(null); - downstreamSnapshot.set(null); - responseTraceParent.set(null); - responseTraceState.set(null); - - OwnerServiceSrv.Iface downstreamHandler = new OwnerServiceStub() { - @Override - public Owner getOwner(int id) throws TException { - InvocationSnapshot snapshot = InvocationSnapshot.capture(); - downstreamSnapshot.set(snapshot); - ScenarioSettings settings = scenario.get(); - assertEquals(settings.expectedRequestId(), snapshot.serviceMetadataRequestId); - assertEquals(settings.expectedDeadline(), snapshot.serviceMetadataDeadline); - if (settings.expectTraceHeaders()) { - assertNotNull(snapshot.inboundTraceParent); - assertTrue(snapshot.inboundTraceParent.contains(settings.inboundTraceId)); - assertEquals(settings.traceState, snapshot.inboundTraceState); - } - if (settings.downstreamThrows) { - throw settings.downstreamException; - } - return new Owner(id, "downstream" + id); - } - }; - - Servlet downstreamServlet = createThriftRPCService(OwnerServiceSrv.Iface.class, downstreamHandler); - - OwnerServiceSrv.Iface upstreamHandler = new OwnerServiceStub() { - @Override - public Owner getOwner(int id) throws TException { - ScenarioSettings settings = scenario.get(); - upstreamInitial.set(InvocationSnapshot.capture()); - if (settings.expectTraceHeaders()) { - InvocationSnapshot initial = upstreamInitial.get(); - assertNotNull(initial); - assertEquals(settings.inboundTraceId, initial.serviceTraceId); - assertEquals(TraceContext.NO_PARENT_ID, initial.serviceParentId); - assertEquals(settings.traceState, initial.inboundTraceState); - assertEquals(settings.inboundTraceParent(), initial.inboundTraceParent); - assertEquals(settings.inboundRequestId, initial.serviceMetadataRequestId); - assertEquals(settings.inboundDeadline, initial.serviceMetadataDeadline); - assertEquals(settings.inboundRequestId, - initial.mdcServerMetadataId); - assertEquals(settings.inboundDeadline, - initial.mdcServerMetadataDeadline); - } - - if (settings.propagateLocalMetadata) { - ContextUtils.setCustomMetadataValue(REQUEST_ID_KEY, settings.localRequestId); - ContextUtils.setCustomMetadataValue(DEADLINE_KEY, settings.localDeadline); - Instant deadline = settings.localDeadline != null ? Instant.parse(settings.localDeadline) : null; - ContextUtils.setDeadline(deadline); - ContextUtils.setDeadline(TraceContext.getCurrentTraceData().getServiceSpan(), deadline); - } - - try { - Owner owner = downstreamClient.getOwner(id); - upstreamAfterCall.set(InvocationSnapshot.capture()); - return owner; - } catch (RuntimeException ex) { - upstreamAfterCall.set(InvocationSnapshot.capture()); - throw ex; - } - } - }; - - Servlet upstreamServlet = createThriftRPCService(OwnerServiceSrv.Iface.class, upstreamHandler); - - ServletContextHandler context = new ServletContextHandler(); - context.setContextPath("/"); - context.addServlet(new ServletHolder("downstream", downstreamServlet), "/downstream"); - context.addServlet(new ServletHolder("upstream", upstreamServlet), "/upstream"); - HandlerCollection collection = (HandlerCollection) server.getHandler(); - collection.addHandler(context); - context.start(); - - downstreamClient = createThriftRPCClient(OwnerServiceSrv.Iface.class, new TimestampIdGenerator(), null, - getUrlString("/downstream")); - } - - @Test - public void shouldStartFreshTraceAndPropagateMetadata() throws Exception { - ScenarioSettings settings = ScenarioSettings.fresh("fresh-trace"); - scenario.set(settings); - - try (CloseableHttpClient httpClient = HttpClients.custom() - .addResponseInterceptorLast(this::captureResponseHeaders) - .build()) { - OwnerServiceSrv.Iface client = createThriftRPCClient(OwnerServiceSrv.Iface.class, - new TimestampIdGenerator(), null, null, getUrlString("/upstream"), networkTimeout, httpClient); - - Owner owner = client.getOwner(42); - assertEquals(new Owner(42, "downstream42"), owner); - } - - InvocationSnapshot upstream = upstreamInitial.get(); - InvocationSnapshot after = upstreamAfterCall.get(); - InvocationSnapshot downstream = downstreamSnapshot.get(); - - assertNotNull(upstream); - assertNotNull(after); - assertNotNull(downstream); - - assertEquals(TraceContext.NO_PARENT_ID, upstream.serviceParentId); - assertEquals(upstream.serviceTraceId, downstream.serviceTraceId); - assertEquals(settings.localRequestId, downstream.serviceMetadataRequestId); - assertEquals(settings.localDeadline, downstream.serviceMetadataDeadline); - assertEquals(settings.localRequestId, downstream.mdcServerMetadataId); - assertEquals(settings.localDeadline, downstream.mdcServerMetadataDeadline); - assertEquals(settings.localRequestId, after.mdcServerMetadataId); - assertEquals(settings.localDeadline, after.mdcServerMetadataDeadline); - assertFalse(upstream.clientSpanFilled); - - assertNotNull(upstream.otelTraceId); - assertEquals(32, upstream.otelTraceId.length()); - assertNotEquals("00000000000000000000000000000000", upstream.otelTraceId); - assertEquals(upstream.otelTraceId, downstream.otelTraceId); - assertEquals(upstream.otelTraceId, after.otelTraceId); - assertFalse(after.clientSpanFilled); - assertNull(responseTraceState.get()); - assertNotNull(responseTraceParent.get()); - assertTrue(responseTraceParent.get().contains(upstream.otelTraceId)); - - SpanStructure spans = SpanStructure.from(finishedSpans()); - spans.assertServerTraceConsistency(); - spans.assertHasRootServer(); - spans.assertHasServerHierarchy(); - spans.assertServerStatus(StatusCode.UNSET, StatusCode.OK); - spans.assertClientStatus(StatusCode.UNSET, StatusCode.OK); - } - - @Test - public void shouldRestoreIncomingTraceHeadersAndEchoResponse() throws Exception { - ScenarioSettings settings = ScenarioSettings.restored( - "c9a6462b3f4e40c4baf3972f9b9b9d10", - "3d2a1f0e5c7b4821", - "vendor=ot", - "req-restored", - "2026-06-01T10:15:30Z"); - scenario.set(settings); - - try (CloseableHttpClient httpClient = HttpClients.custom() - .addRequestInterceptorLast((request, entity, ctx) -> injectInboundHeaders(request, settings)) - .addResponseInterceptorLast(this::captureResponseHeaders) - .build()) { - OwnerServiceSrv.Iface client = createThriftRPCClient(OwnerServiceSrv.Iface.class, - new TimestampIdGenerator(), null, null, getUrlString("/upstream"), networkTimeout, httpClient); - - Owner owner = client.getOwner(7); - assertEquals(new Owner(7, "downstream7"), owner); - } - - InvocationSnapshot upstream = upstreamInitial.get(); - - assertNotNull(upstream); - assertEquals(settings.inboundTraceId, upstream.serviceTraceId); - assertEquals(TraceContext.NO_PARENT_ID, upstream.serviceParentId); - assertEquals(settings.inboundRequestId, upstream.serviceMetadataRequestId); - assertEquals(settings.inboundDeadline, upstream.serviceMetadataDeadline); - assertEquals(settings.inboundRequestId, upstream.mdcServerMetadataId); - assertEquals(settings.inboundDeadline, upstream.mdcServerMetadataDeadline); - - InvocationSnapshot downstream = downstreamSnapshot.get(); - assertNotNull(downstream); - assertEquals(settings.inboundTraceId, downstream.serviceTraceId); - assertEquals(settings.expectedRequestId(), downstream.serviceMetadataRequestId); - assertEquals(settings.expectedDeadline(), downstream.serviceMetadataDeadline); - assertEquals(settings.traceState, downstream.inboundTraceState); - assertEquals(settings.expectedRequestId(), downstream.mdcServerMetadataId); - assertEquals(settings.expectedDeadline(), downstream.mdcServerMetadataDeadline); - InvocationSnapshot after = upstreamAfterCall.get(); - assertEquals(settings.expectedRequestId(), after.mdcServerMetadataId); - assertEquals(settings.expectedDeadline(), after.mdcServerMetadataDeadline); - - assertNotNull(responseTraceParent.get()); - assertEquals(settings.inboundTraceParent(), responseTraceParent.get()); - assertEquals(settings.traceState, responseTraceState.get()); - - SpanStructure spans = SpanStructure.from(finishedSpans()); - spans.assertServerTraceConsistency(); - spans.assertHasRootServer(); - spans.assertHasServerHierarchy(); - spans.assertServerStatus(StatusCode.UNSET, StatusCode.OK); - spans.assertClientStatus(StatusCode.UNSET, StatusCode.OK); - assertFalse(after.clientSpanFilled); - } - - @Test - public void shouldMarkErrorSpanWhenDownstreamThrows() throws Exception { - ScenarioSettings settings = ScenarioSettings.error("downstream failure"); - scenario.set(settings); - - try (CloseableHttpClient httpClient = HttpClients.custom() - .addResponseInterceptorLast(this::captureResponseHeaders) - .build()) { - OwnerServiceSrv.Iface client = createThriftRPCClient(OwnerServiceSrv.Iface.class, - new TimestampIdGenerator(), null, null, getUrlString("/upstream"), networkTimeout, httpClient); - - try { - client.getOwner(5); - fail("Expected WRuntimeException"); - } catch (dev.vality.woody.api.flow.error.WRuntimeException ex) { - assertEquals(dev.vality.woody.api.flow.error.WErrorType.UNEXPECTED_ERROR, - ex.getErrorDefinition().getErrorType()); - assertEquals(dev.vality.woody.api.flow.error.WErrorSource.EXTERNAL, - ex.getErrorDefinition().getGenerationSource()); - assertEquals(dev.vality.woody.api.flow.error.WErrorSource.EXTERNAL, - ex.getErrorDefinition().getErrorSource()); - assertEquals("RuntimeException:downstream failure", - ex.getErrorDefinition().getErrorReason()); - } - } - - InvocationSnapshot upstream = upstreamInitial.get(); - InvocationSnapshot downstream = downstreamSnapshot.get(); - InvocationSnapshot after = upstreamAfterCall.get(); - - assertNotNull(upstream); - assertNotNull(downstream); - assertNotNull(after); - - SpanStructure spans = SpanStructure.from(finishedSpans()); - spans.assertHasRootServer(); - spans.assertHasServerHierarchy(); - } - - @Test - public void shouldHandleMissingMetadataGracefully() throws Exception { - ScenarioSettings settings = ScenarioSettings.missingMetadata(); - scenario.set(settings); - - try (CloseableHttpClient httpClient = HttpClients.custom() - .addRequestInterceptorLast((request, entity, ctx) -> { - request.setHeader(TRACE_PARENT_HEADER, - String.format("00-%s-%s-01", settings.inboundTraceId, settings.inboundSpanId)); - request.setHeader("woody.trace-id", settings.inboundTraceId); - request.setHeader("woody.span-id", settings.inboundSpanId); - request.setHeader("woody.parent-id", TraceContext.NO_PARENT_ID); - }) - .addResponseInterceptorLast(this::captureResponseHeaders) - .build()) { - OwnerServiceSrv.Iface client = createThriftRPCClient(OwnerServiceSrv.Iface.class, - new TimestampIdGenerator(), null, null, getUrlString("/upstream"), networkTimeout, httpClient); - - Owner owner = client.getOwner(9); - assertEquals(new Owner(9, "downstream9"), owner); - } - - InvocationSnapshot upstream = upstreamInitial.get(); - InvocationSnapshot downstream = downstreamSnapshot.get(); - - assertNotNull(upstream); - assertNotNull(downstream); - assertNull(upstream.serviceMetadataRequestId); - assertNull(downstream.serviceMetadataRequestId); - assertNull(downstream.mdcServerMetadataId); - - SpanStructure spans = SpanStructure.from(finishedSpans()); - spans.assertServerStatus(StatusCode.UNSET, StatusCode.OK); - spans.assertClientStatus(StatusCode.UNSET, StatusCode.OK); - } - - private void injectInboundHeaders(HttpRequest request, ScenarioSettings settings) { - request.setHeader(TRACE_PARENT_HEADER, settings.inboundTraceParent()); - request.setHeader(TRACE_STATE_HEADER, settings.traceState); - request.setHeader("woody.trace-id", settings.inboundTraceId); - request.setHeader("woody.span-id", settings.inboundSpanId); - request.setHeader("woody.parent-id", TraceContext.NO_PARENT_ID); - request.setHeader("woody.meta." + REQUEST_ID_KEY, settings.inboundRequestId); - request.setHeader("woody.meta." + DEADLINE_KEY, settings.inboundDeadline); - } - - private void captureResponseHeaders(HttpResponse response, EntityDetails entityDetails, HttpContext context) - throws HttpException, IOException { - if (entityDetails != null) { - entityDetails.getContentLength(); - } - if (context != null) { - context.hashCode(); - } - if (response.getFirstHeader(TRACE_PARENT_HEADER) != null) { - responseTraceParent.set(response.getFirstHeader(TRACE_PARENT_HEADER).getValue()); - } - if (response.getFirstHeader(TRACE_STATE_HEADER) != null) { - responseTraceState.set(response.getFirstHeader(TRACE_STATE_HEADER).getValue()); - } - } - - private static List finishedSpans() { - if (sdkTracerProvider != null) { - sdkTracerProvider.forceFlush().join(5, TimeUnit.SECONDS); - } - return SPAN_EXPORTER.getFinishedSpans(); - } - - private static final class ScenarioSettings { - private final boolean propagateLocalMetadata; - private final boolean downstreamThrows; - private final RuntimeException downstreamException; - private final String localRequestId; - private final String localDeadline; - private final String inboundTraceId; - private final String inboundSpanId; - private final String traceState; - private final String inboundRequestId; - private final String inboundDeadline; - - private ScenarioSettings(boolean propagateLocalMetadata, boolean downstreamThrows, - RuntimeException downstreamException, String localRequestId, - String localDeadline, String inboundTraceId, String inboundSpanId, - String traceState, String inboundRequestId, String inboundDeadline) { - this.propagateLocalMetadata = propagateLocalMetadata; - this.downstreamThrows = downstreamThrows; - this.downstreamException = downstreamException; - this.localRequestId = localRequestId; - this.localDeadline = localDeadline; - this.inboundTraceId = inboundTraceId; - this.inboundSpanId = inboundSpanId; - this.traceState = traceState; - this.inboundRequestId = inboundRequestId; - this.inboundDeadline = inboundDeadline; - } - - static ScenarioSettings fresh(String prefix) { - String futureDeadline = Instant.now().plusSeconds(600).toString(); - return new ScenarioSettings(true, false, null, - prefix + "-req", - futureDeadline, - null, null, null, null, null); - } - - static ScenarioSettings restored(String traceId, String spanId, String traceState, - String requestId, String deadline) { - return new ScenarioSettings(false, false, null, - null, null, traceId, spanId, traceState, requestId, deadline); - } - - static ScenarioSettings error(String message) { - return new ScenarioSettings(false, true, new RuntimeException(message), - null, null, null, null, null, null, null); - } - - static ScenarioSettings missingMetadata() { - return new ScenarioSettings(false, false, null, - null, null, - "d4c1ecdb5e9240b1964280a8f1f34ce1", - "71a3f955acbd42c9", - null, null, null); - } - - boolean expectTraceHeaders() { - return inboundTraceId != null && inboundSpanId != null; - } - - String inboundTraceParent() { - if (!expectTraceHeaders()) { - return null; - } - return String.format("00-%s-%s-01", inboundTraceId, inboundSpanId); - } - - String expectedRequestId() { - if (propagateLocalMetadata && localRequestId != null) { - return localRequestId; - } - return inboundRequestId; - } - - String expectedDeadline() { - if (propagateLocalMetadata && localDeadline != null) { - return localDeadline; - } - return inboundDeadline; - } - } - - private static final class InvocationSnapshot { - private final boolean clientSpanFilled; - private final String serviceTraceId; - private final String serviceSpanId; - private final String serviceParentId; - private final String serviceMetadataRequestId; - private final String serviceMetadataDeadline; - private final String inboundTraceParent; - private final String inboundTraceState; - private final String otelTraceId; - private final String otelSpanId; - private final String mdcServerMetadataId; - private final String mdcServerMetadataDeadline; - - private InvocationSnapshot(boolean clientSpanFilled, String serviceTraceId, String serviceSpanId, - String serviceParentId, String serviceMetadataRequestId, - String serviceMetadataDeadline, String inboundTraceParent, - String inboundTraceState, String otelTraceId, String otelSpanId, - String mdcServerMetadataId, String mdcServerMetadataDeadline) { - this.clientSpanFilled = clientSpanFilled; - this.serviceTraceId = serviceTraceId; - this.serviceSpanId = serviceSpanId; - this.serviceParentId = serviceParentId; - this.serviceMetadataRequestId = serviceMetadataRequestId; - this.serviceMetadataDeadline = serviceMetadataDeadline; - this.inboundTraceParent = inboundTraceParent; - this.inboundTraceState = inboundTraceState; - this.otelTraceId = otelTraceId; - this.otelSpanId = otelSpanId; - this.mdcServerMetadataId = mdcServerMetadataId; - this.mdcServerMetadataDeadline = mdcServerMetadataDeadline; - } - - private static InvocationSnapshot capture() { - TraceData traceData = TraceContext.getCurrentTraceData(); - if (traceData == null) { - return new InvocationSnapshot(false, null, null, null, null, null, - null, null, null, null, null, null); - } - ContextSpan serviceSpan = traceData.getServiceSpan(); - SpanContext spanContext = traceData.getOtelSpan().getSpanContext(); - return new InvocationSnapshot(traceData.getClientSpan().isFilled(), - serviceSpan.getSpan().getTraceId(), - serviceSpan.getSpan().getId(), - serviceSpan.getSpan().getParentId(), - ContextUtils.getCustomMetadataValue(serviceSpan, String.class, REQUEST_ID_KEY), - ContextUtils.getCustomMetadataValue(serviceSpan, String.class, DEADLINE_KEY), - traceData.getInboundTraceParent(), - traceData.getInboundTraceState(), - spanContext.getTraceId(), - spanContext.getSpanId(), - MDC.get("rpc.server.metadata." + REQUEST_ID_KEY), - MDC.get("rpc.server.metadata." + DEADLINE_KEY)); - } - } - - private static final class SpanStructure { - private final List clientSpans; - private final List serverSpans; - - private SpanStructure(List clientSpans, List serverSpans) { - this.clientSpans = clientSpans; - this.serverSpans = serverSpans; - } - - static SpanStructure from(List spans) { - List clients = spans.stream() - .filter(span -> span.getKind() == SpanKind.CLIENT) - .collect(Collectors.toList()); - List servers = spans.stream() - .filter(span -> span.getKind() == SpanKind.SERVER) - .collect(Collectors.toList()); - if (clients.isEmpty()) { - throw new AssertionError("Missing client spans"); - } - if (servers.isEmpty()) { - throw new AssertionError("Missing server spans"); - } - return new SpanStructure(clients, servers); - } - - void assertServerTraceConsistency() { - var serverTraceIds = serverSpans.stream() - .map(SpanData::getTraceId) - .collect(Collectors.toSet()); - assertEquals("Server spans must share trace", 1, serverTraceIds.size()); - } - - void assertHasRootServer() { - var serverIds = serverSpans.stream().map(SpanData::getSpanId).collect(Collectors.toSet()); - boolean hasRoot = serverSpans.stream() - .anyMatch(span -> !serverIds.contains(span.getParentSpanId())); - assertTrue("Expected upstream server span", hasRoot); - } - - void assertHasServerHierarchy() { - var serverIds = serverSpans.stream().map(SpanData::getSpanId).collect(Collectors.toSet()); - boolean hasHierarchy = serverSpans.stream() - .anyMatch(span -> serverIds.contains(span.getParentSpanId())); - assertTrue("Expected downstream server span", hasHierarchy); - } - - void assertServerStatus(StatusCode... expected) { - var allowed = Arrays.stream(expected).collect(Collectors.toSet()); - serverSpans.forEach(span -> assertTrue("Unexpected server status " + span.getStatus(), - allowed.contains(span.getStatus().getStatusCode()))); - } - - void assertClientStatus(StatusCode... expected) { - var allowed = Arrays.stream(expected).collect(Collectors.toSet()); - clientSpans.forEach(span -> assertTrue("Unexpected client status " + span.getStatus(), - allowed.contains(span.getStatus().getStatusCode()))); - } - - } - - private static final class RecordingSpanExporter implements SpanExporter { - private final List spans = new java.util.concurrent.CopyOnWriteArrayList<>(); - - @Override - public CompletableResultCode export(Collection spans) { - this.spans.addAll(spans); - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode shutdown() { - spans.clear(); - return CompletableResultCode.ofSuccess(); - } - - List getFinishedSpans() { - return spans; - } - - void reset() { - spans.clear(); - } - } -} diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/error/THProviderErrorMapperTest.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/error/THProviderErrorMapperTest.java index ec3e0a8f..685f0e69 100644 --- a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/error/THProviderErrorMapperTest.java +++ b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/error/THProviderErrorMapperTest.java @@ -33,9 +33,6 @@ public void setUp() { @After public void tearDown() { - if (testTraceData != null) { - testTraceData.getOtelSpan().end(); - } TraceContext.setCurrentTraceData(originalTraceData); } From 50104f9127a474bb91bd9f03f17519f1d5711426 Mon Sep 17 00:00:00 2001 From: "f.shim" Date: Fri, 27 Mar 2026 12:18:36 +0700 Subject: [PATCH 2/5] Bump version --- libthrift/pom.xml | 2 +- pom.xml | 2 +- woody-api/pom.xml | 2 +- woody-thrift/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libthrift/pom.xml b/libthrift/pom.xml index a82dc6b1..4fb4f9d7 100644 --- a/libthrift/pom.xml +++ b/libthrift/pom.xml @@ -7,7 +7,7 @@ woody dev.vality.woody - 2.1.0 + 2.2.0 libthrift diff --git a/pom.xml b/pom.xml index 2dd406fd..43bc353b 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ pom dev.vality.woody woody - 2.1.0 + 2.2.0 Woody Java Java implementation for Woody spec diff --git a/woody-api/pom.xml b/woody-api/pom.xml index 4b4966b0..2621f92e 100644 --- a/woody-api/pom.xml +++ b/woody-api/pom.xml @@ -7,7 +7,7 @@ woody dev.vality.woody - 2.1.0 + 2.2.0 woody-api diff --git a/woody-thrift/pom.xml b/woody-thrift/pom.xml index 10bd7cd2..d45c42af 100644 --- a/woody-thrift/pom.xml +++ b/woody-thrift/pom.xml @@ -7,7 +7,7 @@ woody dev.vality.woody - 2.1.0 + 2.2.0 woody-thrift From f3a2dbd9bbbca2139f99b9a2c666a1b2ea43d876 Mon Sep 17 00:00:00 2001 From: "f.shim" Date: Fri, 27 Mar 2026 14:39:41 +0700 Subject: [PATCH 3/5] clear MD --- README.md | 28 +++++++------------ context.md | 27 +++++++----------- woody-api/woody-api.md | 12 ++++---- .../src/test/resources/log4j.properties | 2 +- woody-thrift/woody-thrift.md | 13 ++++----- 5 files changed, 32 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 572d6a77..e26867fb 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ Java реализация [Библиотеки RPC вызовов][rpc-lib] д ## Ключевые возможности - Сквозная трассировка вызовов через `TraceData`, автоматическое измерение - длительности и интеграция со SLF4J MDC и OpenTelemetry. -- Расширенный MDC: автоматически публикует идентификаторы Woody/OTel, дедлайны, + длительности и интеграция со SLF4J MDC. +- Расширенный MDC: автоматически публикует идентификаторы Woody, дедлайны, RPC-метаданные и может отключаться через `-Dwoody.mdc.extended=false`. - Потокобезопасная обработка фоновых задач с сохранением контекста (`WFlow.create`, `createServiceFork`). @@ -57,14 +57,14 @@ _woody-pom_ и в корневой директории проекта выпо `woody-api`, интеграция `woody-thrift`, а также пропатченный `libthrift` (форк Apache Thrift, переиспользующий HttpClient5 и подключающийся как модуль). -- Основной стек: Java 11, SLF4J, Apache Commons Pool 2, OpenTelemetry - (API/SDK/OTLP), Jakarta Servlet 5, Jetty и EasyMock в тестах. +- Основной стек: Java 11, SLF4J, Apache Commons Pool 2, Jakarta Servlet 5, + Jetty и EasyMock в тестах. ## Woody API - `TraceContext`/`TraceData` управляют client/service span’ами в `ThreadLocal`, автоматически создают `trace_id/span_id`, фиксируют - длительность, синхронизируют SLF4J MDC и завершают OTEL-спаны. + длительность и синхронизируют SLF4J MDC. - `WFlow` и `flow.concurrent` оборачивают `Runnable`/`Callable`/ `ExecutorService`, сохраняя контекст при выполнении в других потоках, поддерживают форки с новыми root- и service-span’ами. @@ -88,7 +88,7 @@ _woody-pom_ и в корневой директории проекта выпо - Thrift over HTTP поверх Woody. - Клиенты (`THClientBuilder`, `THSpawnClientBuilder`, `THPooledClientBuilder`) создают `TServiceClient`, добавляют - транспортные и message перехватчики (метаданные, traceparent, события), + транспортные и message перехватчики (метаданные, события), управляют ресурсами HttpClient5. - Сервисы (`THServiceBuilder`) собирают `TServlet` с обёртками над `TProcessor`, прокидывая `TraceContext.forService`, подключая @@ -98,8 +98,7 @@ _woody-pom_ и в корневой директории проекта выпо - Транспорт и сообщения расширяются через bundles (`MetadataExtensionBundle` и др.), создавая `THCExtensionContext`/ `THSExtensionContext` для клиента и сервиса. - - Поддержка W3C traceparent (`TraceParentUtils`), заполнение - дедлайнов/ошибок в метаданные, HTTP-логгеры. + - Заполнение дедлайнов/ошибок в метаданные, HTTP-логгеры. - Дополнительные пакеты: `error` (конвертация исключений и HTTP-статусов), `event` (логирование), `transport` (конфигурация HTTP servlet’ов и клиентов). @@ -115,16 +114,9 @@ _woody-pom_ и в корневой директории проекта выпо - `woody-api/src/test` покрывает генераторы идентификаторов, трассировку и прокси. - `woody-thrift/src/test` (Jetty quickstart + EasyMock) проверяет - HTTP-интеграцию, обработку исключений и метаданные, включая - интеграционные сценарии `TraceLifecycleIntegrationTest` для проверки - сквозной OpenTelemetry-трассировки, восстановления контекста, ошибок и - работы с неполными заголовками. + HTTP-интеграцию, обработку исключений и метаданные. - Профиль `gen_thrift_classes` включает `thrift-maven-plugin` для генерации Thrift IDL. -- Интеграционные тесты `MetadataMdcPropagationTest` и - `TraceLifecycleIntegrationTest` контролируют перенос MDC-метаданных, - OpenTelemetry-трассировку и восстановление контекста при ошибках. - ## Дополнительные материалы - [Контекст Woody Java](context.md) — сводный обзор модулей, @@ -134,8 +126,8 @@ _woody-pom_ и в корневой директории проекта выпо Реализация обеспечивает сквозную трассировку, управление временем жизни span’ов и доступ к событиям через единую API-обвязку; `woody-thrift` поверх -неё инкапсулирует создание HTTP-клиентов и сервисов Thrift с `traceparent`, -логированием и расширяемыми метаданными, опираясь на локально +неё инкапсулирует создание HTTP-клиентов и сервисов Thrift с логированием и +расширяемыми метаданными, опираясь на локально модифицированный `libthrift`. [rpc-lib]: http://52.29.202.218/design/ms/platform/rpc-lib/ diff --git a/context.md b/context.md index b92993b3..df92acd4 100644 --- a/context.md +++ b/context.md @@ -5,8 +5,7 @@ - Maven multi-module library delivering RPC tracing infrastructure for microservices. - Java 11 baseline; core dependencies include SLF4J, Apache Commons Pool 2, - OpenTelemetry (API/SDK/OTLP exporter), Jakarta Servlet 5, HttpClient5, Jetty - (tests), EasyMock. + Jakarta Servlet 5, HttpClient5, Jetty (tests), EasyMock. - Modules share version `woody` (root POM); `dependencyManagement` keeps `woody- api` version-aligned. @@ -15,9 +14,8 @@ ### woody-api - Thread-local tracing via `TraceContext`/`TraceData` managing client/service - spans, auto ID generation, duration tracking, SLF4J MDC sync, OTEL span - lifecycle. -- `MDCUtils` публикует trace/span идентификаторы Woody и OpenTelemetry, + spans, auto ID generation, duration tracking and SLF4J MDC sync. +- `MDCUtils` публикует trace/span идентификаторы Woody, дедлайны и RPC-метаданные (отключаемо через системное свойство `woody.mdc.extended`). - Concurrency helpers (`WFlow`, `WCallable`, `WRunnable`, `WExecutorService`) @@ -42,13 +40,12 @@ - Thrift-over-HTTP implementation layered on woody-api. - Client builders (`THClientBuilder`, `THSpawnClientBuilder`, `THPooledClientBuilder`) construct `TServiceClient`, inject message/transport - interceptors, traceparent propagation, metadata extensions, logging - (`THCEventLogListener`); support custom or pooled HttpClient5. + interceptors, metadata extensions, logging (`THCEventLogListener`); support + custom or pooled HttpClient5. - Service builder (`THServiceBuilder`) wraps `TProcessor` into `TServlet`, applies transport interceptors, `THErrorMapProcessor`, logging (`THSEventLogListener`), and ensures `TraceContext.forService`. -- Extension bundles produce `THCExtensionContext`/`THSExtensionContext`; - `TraceParentUtils` handles W3C traceparent parsing/serialization. +- Extension bundles produce `THCExtensionContext`/`THSExtensionContext`. - Supplemental packages: `error` (exception ↔ response mapping), `event` (HTTP logging), `transport` (servlet/client wiring). - Обновлённый `THProviderErrorMapper` синхронизирует статус, источники ошибок, @@ -72,17 +69,13 @@ - `woody-api/src/test`: ID generators, tracing logic, proxy behavior. - `woody-thrift/src/test`: Jetty quickstart servers + EasyMock cover HTTP - integration, metadata propagation, error mapping, а также свежие - интеграционные сценарии `TraceLifecycleIntegrationTest`, проверяющие - сквозную OpenTelemetry-трассировку (новый/восстановленный контекст, - обработку ошибок, отсутствие обязательных метаданных). -- Дополнительно `THProviderErrorMapperTest` и `MetadataMdcPropagationTest` - контролируют обработку ошибок и перенос MDC/OTel данных. + integration, metadata propagation and error mapping. +- Дополнительно `THProviderErrorMapperTest` контролирует обработку ошибок. ## Key Concepts for Agents - Always maintain root/service/client span consistency; `TraceContext` - orchestrates init/destroy hooks and ensures MDC/Otel sync. + orchestrates init/destroy hooks and ensures MDC sync. - Cross-thread execution must wrap tasks with `WFlow.create`/`createServiceFork`. - Interceptors are composable; metadata extensions rely on extension bundles @@ -122,4 +115,4 @@ - For new metadata, implement `MetadataExtensionKit` and include via builder `withMetaExtensions`. - Для фоновых задач используйте `WFlow.createServiceFork(...)` — он создаёт - новый service-span и корректно инициализирует OpenTelemetry контекст. + новый service-span и корректно инициализирует контекст. diff --git a/woody-api/woody-api.md b/woody-api/woody-api.md index 9f9e6cdf..569e6b93 100644 --- a/woody-api/woody-api.md +++ b/woody-api/woody-api.md @@ -1,12 +1,12 @@ # dev.vality.woody.api Java API, предоставляющее основу для реализации сквозной трассировки событий в распределенной системе. -Основан на thread-context подходе (информация о цепочке хранится в контексте, который привязан к потоку, в котором началось выполнение или обработка запроса) и синхронизирован с OpenTelemetry span’ами, что проверяется свежими интеграционными тестами в модуле `woody-thrift`. +Основан на thread-context подходе (информация о цепочке хранится в контексте, который привязан к потоку, в котором началось выполнение или обработка запроса). -## OpenTelemetry и MDC +## MDC -- `TraceData` содержит ссылку на активный OTEL-span; `MDCUtils` автоматически - публикует `otel_trace_id`, `otel_span_id`, флаги трассировки и дедлайны. +- `MDCUtils` автоматически публикует `trace_id`, `span_id`, `parent_id`, + дедлайны и расширенные RPC-поля. - Расширенные MDC-поля (`rpc.client.*`, `rpc.server.*`, RPC-метаданные) включены по умолчанию и могут быть отключены системным параметром `-Dwoody.mdc.extended=false`. @@ -15,7 +15,7 @@ Java API, предоставляющее основу для реализаци - `WFlow.createServiceFork(...)` создаёт новый service-span с переданными генераторами идентификаторов, очищая длительность/временные метки и - синхронизируя OTEL-контекст. + синхронизируя контекст. - Фабрики `WCallable`/`WRunnable` принимают заранее подготовленный `TraceData`, что позволяет запускать задачи в пулах с сохранением или форком контекста. @@ -70,4 +70,4 @@ WRunnable.createFork(yourForkedRunnable).run(); // All requests here're root req ``` Аналогично для `Callable`: -`WCallable.createFork(yourForkedCallable).call();`. \ No newline at end of file +`WCallable.createFork(yourForkedCallable).call();`. diff --git a/woody-thrift/src/test/resources/log4j.properties b/woody-thrift/src/test/resources/log4j.properties index 4443f630..2d3654fa 100644 --- a/woody-thrift/src/test/resources/log4j.properties +++ b/woody-thrift/src/test/resources/log4j.properties @@ -2,4 +2,4 @@ log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=[%t] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p Span[%X{trace_id}-%X{span_id}-%X{parent_id}, deadline: %X{deadline}] OtelSpan[%X{otel_trace_id}-%X{otel_span_id}] - %m%n +log4j.appender.stdout.layout.ConversionPattern=[%t] %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p Span[%X{trace_id}-%X{span_id}-%X{parent_id}, deadline: %X{deadline}] - %m%n diff --git a/woody-thrift/woody-thrift.md b/woody-thrift/woody-thrift.md index fb83ebfb..60f15015 100644 --- a/woody-thrift/woody-thrift.md +++ b/woody-thrift/woody-thrift.md @@ -81,17 +81,14 @@ Servlet service = serviceBuilder.build(ThriftServiceSrv.Iface.class, handler); ### Интеграционные тесты -Для проверки сквозной OpenTelemetry-трассировки, восстановления контекста, -обработки ошибок и работы без обязательных метаданных используйте -интеграционный набор `TraceLifecycleIntegrationTest` в модуле `woody-thrift`. +Для проверки обработки ошибок и HTTP-интеграции используйте тесты модуля +`woody-thrift`. ### Обработка ошибок и метаданных - Маппер `THProviderErrorMapper` сопоставляет HTTP/Thrift ошибки с `WErrorDefinition`, заполняет `THMetadataProperties` (тип/подтип) и учитывает перехваченные ошибки транспортных интерсепторов. -- `MetadataMdcPropagationTest` и `THProviderErrorMapperTest` служат примерами - того, как проверять перенос MDC-метаданных и корректность кодификации - транспортных исключений. - - +- `THProviderErrorMapperTest` и `TestClientAndServerHttpHeaders` служат + примерами того, как проверять перенос MDC-метаданных и корректность + кодификации транспортных исключений. From 2bb22c5fde0fa5fba7064d7ddafca058a6d823d9 Mon Sep 17 00:00:00 2001 From: "f.shim" Date: Fri, 27 Mar 2026 14:43:05 +0700 Subject: [PATCH 4/5] restore MetadataMdcPropagationTest --- .../impl/http/MetadataMdcPropagationTest.java | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java diff --git a/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java new file mode 100644 index 00000000..949b3d34 --- /dev/null +++ b/woody-thrift/src/test/java/dev/vality/woody/thrift/impl/http/MetadataMdcPropagationTest.java @@ -0,0 +1,213 @@ +package dev.vality.woody.thrift.impl.http; + +import dev.vality.woody.api.MDCUtils; +import dev.vality.woody.api.event.ClientEventListener; +import dev.vality.woody.api.event.ClientEventType; +import dev.vality.woody.api.event.ServiceEventListener; +import dev.vality.woody.api.generator.TimestampIdGenerator; +import dev.vality.woody.api.trace.ContextUtils; +import dev.vality.woody.api.trace.context.TraceContext; +import dev.vality.woody.api.trace.context.metadata.MetadataExtensionKit; +import dev.vality.woody.rpc.Owner; +import dev.vality.woody.rpc.OwnerServiceSrv; +import dev.vality.woody.thrift.impl.http.event.THClientEvent; +import jakarta.servlet.Servlet; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.core5.http.EntityDetails; +import org.apache.hc.core5.http.HttpException; +import org.apache.hc.core5.http.HttpRequest; +import org.apache.hc.core5.http.protocol.HttpContext; +import org.apache.thrift.TException; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.MDC; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class MetadataMdcPropagationTest extends AbstractTest { + + private static final String X_REQUEST_ID = "068e67b4-74bc-4333-9c14-090e6acc3227"; + private static final String X_REQUEST_DEADLINE = "2025-01-01T12:30:00Z"; + private static final String TRACE_ID = "4e0e9f8d8d8044f9b65a3b0f5cdfc2d1"; + private static final String SPAN_ID = "1a2b3c4d5e6f7081"; + + private final AtomicReference upstreamMetadataId = new AtomicReference<>(); + private final AtomicReference upstreamMetadataDeadline = new AtomicReference<>(); + private final AtomicReference upstreamMdcId = new AtomicReference<>(); + private final AtomicReference upstreamMdcDeadline = new AtomicReference<>(); + private final AtomicReference downstreamMetadataId = new AtomicReference<>(); + private final AtomicReference downstreamMetadataDeadline = new AtomicReference<>(); + private final AtomicReference downstreamMdcId = new AtomicReference<>(); + private final AtomicReference downstreamMdcDeadline = new AtomicReference<>(); + private final AtomicReference downstreamRpcServerService = new AtomicReference<>(); + private final AtomicReference downstreamRpcServerFunction = new AtomicReference<>(); + private final AtomicReference downstreamRpcServerUrl = new AtomicReference<>(); + private final AtomicReference upstreamRpcServerService = new AtomicReference<>(); + private final AtomicReference upstreamRpcServerFunction = new AtomicReference<>(); + private final AtomicReference upstreamRpcServerUrl = new AtomicReference<>(); + private final AtomicReference upstreamRpcClientService = new AtomicReference<>(); + private final AtomicReference upstreamRpcClientFunction = new AtomicReference<>(); + private final AtomicReference upstreamRpcClientUrl = new AtomicReference<>(); + private final AtomicReference upstreamClientPrefixAfterCall = new AtomicReference<>(); + + private OwnerServiceSrv.Iface downstreamClient; + + @Override + protected Servlet createThriftRPCService(Class iface, T handler, + ServiceEventListener eventListener, + List extensionKits) { + THServiceBuilder serviceBuilder = new THServiceBuilder(); + serviceBuilder.withLogEnabled(false); + if (eventListener != null) { + serviceBuilder.withEventListener(eventListener); + } + serviceBuilder.withMetaExtensions(extensionKits); + return serviceBuilder.build(iface, handler); + } + + @Before + public void setUpServices() throws Exception { + OwnerServiceSrv.Iface downstreamHandler = new OwnerServiceStub() { + @Override + public Owner getOwner(int id) throws TException { + downstreamMetadataId.set(ContextUtils.getCustomMetadataValue(String.class, + "user-identity.x-request-id")); + downstreamMetadataDeadline.set(ContextUtils.getCustomMetadataValue(String.class, + "user-identity.x-request-deadline")); + downstreamMdcId.set(MDC.get("rpc.server.metadata.user-identity.x-request-id")); + downstreamMdcDeadline.set(MDC.get("rpc.server.metadata.user-identity.x-request-deadline")); + downstreamRpcServerService.set(MDC.get("rpc.server.service")); + downstreamRpcServerFunction.set(MDC.get("rpc.server.function")); + downstreamRpcServerUrl.set(MDC.get("rpc.server.url")); + return new Owner(id, "downstream"); + } + }; + + Servlet downstreamServlet = createThriftRPCService(OwnerServiceSrv.Iface.class, downstreamHandler); + + OwnerServiceSrv.Iface upstreamHandler = new OwnerServiceStub() { + @Override + public Owner getOwner(int id) throws TException { + upstreamMetadataId.set(ContextUtils.getCustomMetadataValue(String.class, + "user-identity.x-request-id")); + upstreamMetadataDeadline.set(ContextUtils.getCustomMetadataValue(String.class, + "user-identity.x-request-deadline")); + upstreamMdcId.set(MDC.get("rpc.server.metadata.user-identity.x-request-id")); + upstreamMdcDeadline.set(MDC.get("rpc.server.metadata.user-identity.x-request-deadline")); + upstreamRpcServerService.set(MDC.get("rpc.server.service")); + upstreamRpcServerFunction.set(MDC.get("rpc.server.function")); + upstreamRpcServerUrl.set(MDC.get("rpc.server.url")); + + Owner result = downstreamClient.getOwner(id); + + upstreamClientPrefixAfterCall.set(MDC.get("rpc.client.service")); + assertNotNull("Active trace context must be available", TraceContext.getCurrentTraceData()); + return result; + } + }; + + Servlet upstreamServlet = createThriftRPCService(OwnerServiceSrv.Iface.class, upstreamHandler); + + org.eclipse.jetty.servlet.ServletContextHandler context = new org.eclipse.jetty.servlet.ServletContextHandler(); + context.setContextPath("/"); + context.addServlet(new org.eclipse.jetty.servlet.ServletHolder("downstream", downstreamServlet), + "/downstream"); + context.addServlet(new org.eclipse.jetty.servlet.ServletHolder("upstream", upstreamServlet), + "/upstream"); + ((org.eclipse.jetty.server.handler.HandlerCollection) server.getHandler()).addHandler(context); + context.start(); + + ClientEventListener clientEventListener = new ClientEventListener() { + @Override + public void notifyEvent(THClientEvent event) { + if (ClientEventType.CLIENT_SEND.equals(event.getEventType())) { + upstreamRpcClientService.set(MDC.get(MDCUtils.TRACE_RPC_CLIENT_PREFIX + "service")); + upstreamRpcClientFunction.set(MDC.get(MDCUtils.TRACE_RPC_CLIENT_PREFIX + "function")); + upstreamRpcClientUrl.set(MDC.get(MDCUtils.TRACE_RPC_CLIENT_PREFIX + "url")); + } + } + }; + + downstreamClient = createThriftRPCClient(OwnerServiceSrv.Iface.class, new TimestampIdGenerator(), + clientEventListener, null, getUrlString("/downstream")); + } + + @Test + public void shouldPropagateMetadataHeadersAndPopulateMdc() throws Exception { + clearCapturedValues(); + + try (CloseableHttpClient httpClient = HttpClients.custom() + .addRequestInterceptorLast(this::injectHeaders) + .build()) { + OwnerServiceSrv.Iface entryClient = createThriftRPCClient(OwnerServiceSrv.Iface.class, + new TimestampIdGenerator(), null, null, getUrlString("/upstream"), networkTimeout, httpClient); + + entryClient.getOwner(42); + } + + assertEquals(X_REQUEST_ID, upstreamMetadataId.get()); + assertEquals(X_REQUEST_DEADLINE, upstreamMetadataDeadline.get()); + assertEquals(X_REQUEST_ID, upstreamMdcId.get()); + assertEquals(X_REQUEST_DEADLINE, upstreamMdcDeadline.get()); + + assertEquals(X_REQUEST_ID, downstreamMetadataId.get()); + assertEquals(X_REQUEST_DEADLINE, downstreamMetadataDeadline.get()); + assertEquals(X_REQUEST_ID, downstreamMdcId.get()); + assertEquals(X_REQUEST_DEADLINE, downstreamMdcDeadline.get()); + assertEquals("OwnerService", downstreamRpcServerService.get()); + assertEquals("getOwner", downstreamRpcServerFunction.get()); + assertTrue("Server URL should contain downstream path", + downstreamRpcServerUrl.get() != null && downstreamRpcServerUrl.get().contains("/downstream")); + assertEquals("OwnerService", upstreamRpcServerService.get()); + assertEquals("getOwner", upstreamRpcServerFunction.get()); + assertTrue("Server URL should contain upstream path", + upstreamRpcServerUrl.get() != null && upstreamRpcServerUrl.get().contains("/upstream")); + assertEquals("OwnerService", upstreamRpcClientService.get()); + assertEquals("getOwner", upstreamRpcClientFunction.get()); + assertEquals(getUrlString("/downstream"), upstreamRpcClientUrl.get()); + assertEquals("OwnerService", upstreamClientPrefixAfterCall.get()); + } + + private void injectHeaders(HttpRequest request, EntityDetails entity, HttpContext context) + throws HttpException, IOException { + if (entity != null) { + entity.getContentLength(); + } + if (context != null) { + context.hashCode(); + } + request.setHeader("woody.meta.user-identity.x-request-id", X_REQUEST_ID); + request.setHeader("woody.meta.user-identity.x-request-deadline", X_REQUEST_DEADLINE); + request.setHeader("woody.trace-id", TRACE_ID); + request.setHeader("woody.span-id", SPAN_ID); + request.setHeader("woody.parent-id", TraceContext.NO_PARENT_ID); + } + + private void clearCapturedValues() { + upstreamMetadataId.set(null); + upstreamMetadataDeadline.set(null); + upstreamMdcId.set(null); + upstreamMdcDeadline.set(null); + downstreamMetadataId.set(null); + downstreamMetadataDeadline.set(null); + downstreamMdcId.set(null); + downstreamMdcDeadline.set(null); + downstreamRpcServerService.set(null); + downstreamRpcServerFunction.set(null); + downstreamRpcServerUrl.set(null); + upstreamRpcServerService.set(null); + upstreamRpcServerFunction.set(null); + upstreamRpcServerUrl.set(null); + upstreamRpcClientService.set(null); + upstreamRpcClientFunction.set(null); + upstreamRpcClientUrl.set(null); + upstreamClientPrefixAfterCall.set(null); + } +} From 280be747c37e1e42a5454143bf9b5652515f96ff Mon Sep 17 00:00:00 2001 From: "f.shim" Date: Fri, 27 Mar 2026 14:55:15 +0700 Subject: [PATCH 5/5] Bump --- libthrift/pom.xml | 2 +- pom.xml | 2 +- woody-api/pom.xml | 2 +- woody-thrift/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libthrift/pom.xml b/libthrift/pom.xml index 4fb4f9d7..4db41875 100644 --- a/libthrift/pom.xml +++ b/libthrift/pom.xml @@ -7,7 +7,7 @@ woody dev.vality.woody - 2.2.0 + 3.0.0 libthrift diff --git a/pom.xml b/pom.xml index 43bc353b..41682045 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ pom dev.vality.woody woody - 2.2.0 + 3.0.0 Woody Java Java implementation for Woody spec diff --git a/woody-api/pom.xml b/woody-api/pom.xml index 2621f92e..a98dc6ea 100644 --- a/woody-api/pom.xml +++ b/woody-api/pom.xml @@ -7,7 +7,7 @@ woody dev.vality.woody - 2.2.0 + 3.0.0 woody-api diff --git a/woody-thrift/pom.xml b/woody-thrift/pom.xml index d45c42af..22d9ed51 100644 --- a/woody-thrift/pom.xml +++ b/woody-thrift/pom.xml @@ -7,7 +7,7 @@ woody dev.vality.woody - 2.2.0 + 3.0.0 woody-thrift