Fix khttp instrumentation in case of absent or read-only headers map (#416)

This commit is contained in:
Nikita Salnikov-Tarnovski 2020-05-20 23:47:25 +03:00 committed by GitHub
parent 4acfeb9ddc
commit a258f1424a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 5 additions and 18 deletions

View File

@ -39,7 +39,7 @@ public class KHttpAdvice {
public static SpanWithScope methodEnter( public static SpanWithScope methodEnter(
@Advice.Argument(value = 0) String method, @Advice.Argument(value = 0) String method,
@Advice.Argument(value = 1) String uri, @Advice.Argument(value = 1) String uri,
@Advice.Argument(value = 2) Map<String, String> headers) { @Advice.Argument(value = 2, readOnly = false) Map<String, String> headers) {
final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(KHttp.class); final int callDepth = CallDepthThreadLocalMap.incrementCallDepth(KHttp.class);
if (callDepth > 0) { if (callDepth > 0) {
@ -53,7 +53,8 @@ public class KHttpAdvice {
final Context context = withSpan(span, Context.current()); final Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, asWritable(headers), SETTER); headers = asWritable(headers);
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, headers, SETTER);
return new SpanWithScope(span, withScopedContext(context)); return new SpanWithScope(span, withScopedContext(context));
} }

View File

@ -21,23 +21,9 @@ import java.util.Map;
public class KHttpHeadersInjectAdapter implements HttpTextFormat.Setter<Map<String, String>> { public class KHttpHeadersInjectAdapter implements HttpTextFormat.Setter<Map<String, String>> {
private static Class emptyMap;
static {
try {
emptyMap = Class.forName("kotlin.collections.EmptyMap");
} catch (ClassNotFoundException e) {
}
}
public static Map<String, String> asWritable(Map<String, String> headers) { public static Map<String, String> asWritable(Map<String, String> headers) {
// EmptyMap is read-only so we have to substitute it with writable instance to be able to inject // Kotlin likes to use read-only data structures, so wrap into new writable map
// headers return new HashMap<>(headers);
if (emptyMap != null && emptyMap.isInstance(headers)) {
return new HashMap<>();
} else {
return headers;
}
} }
public static final KHttpHeadersInjectAdapter SETTER = new KHttpHeadersInjectAdapter(); public static final KHttpHeadersInjectAdapter SETTER = new KHttpHeadersInjectAdapter();