From d9b25d34df897cd3ccb6392a4ff89de261aaa413 Mon Sep 17 00:00:00 2001 From: jason plumb <75337021+breedx-splk@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:03:03 -0700 Subject: [PATCH] Guard against null HttpContext (#6792) Resolves #6787 Co-authored-by: Trask Stalnaker --- .../ApacheHttpAsyncClientInstrumentation.java | 17 +++++++++++------ .../ApacheHttpAsyncClientInstrumentation.java | 18 ++++++++++++------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java b/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java index 849d449e1d..53b9cffb58 100644 --- a/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java +++ b/instrumentation/apache-httpasyncclient-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpasyncclient/ApacheHttpAsyncClientInstrumentation.java @@ -20,6 +20,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import java.io.IOException; import java.util.logging.Logger; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -148,7 +149,7 @@ public class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation private static final Logger logger = Logger.getLogger(WrappedFutureCallback.class.getName()); private final Context parentContext; - private final HttpContext httpContext; + @Nullable private final HttpContext httpContext; private final FutureCallback delegate; private volatile Context context; @@ -171,7 +172,7 @@ public class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation return; } - instrumenter().end(context, otelRequest, getResponse(httpContext), null); + instrumenter().end(context, otelRequest, getResponseFromHttpContext(), null); if (parentContext == null) { completeDelegate(result); @@ -193,7 +194,7 @@ public class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation } // end span before calling delegate - instrumenter().end(context, otelRequest, getResponse(httpContext), ex); + instrumenter().end(context, otelRequest, getResponseFromHttpContext(), ex); if (parentContext == null) { failDelegate(ex); @@ -216,7 +217,7 @@ public class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation // TODO (trask) add "canceled" span attribute // end span before calling delegate - instrumenter().end(context, otelRequest, getResponse(httpContext), null); + instrumenter().end(context, otelRequest, getResponseFromHttpContext(), null); if (parentContext == null) { cancelDelegate(); @@ -246,8 +247,12 @@ public class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation } } - private static HttpResponse getResponse(HttpContext context) { - return (HttpResponse) context.getAttribute(HttpCoreContext.HTTP_RESPONSE); + @Nullable + private HttpResponse getResponseFromHttpContext() { + if (httpContext == null) { + return null; + } + return (HttpResponse) httpContext.getAttribute(HttpCoreContext.HTTP_RESPONSE); } } } diff --git a/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpAsyncClientInstrumentation.java b/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpAsyncClientInstrumentation.java index 85f8ae28c9..5a6885710e 100644 --- a/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpAsyncClientInstrumentation.java +++ b/instrumentation/apache-httpclient/apache-httpclient-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/apachehttpclient/v5_0/ApacheHttpAsyncClientInstrumentation.java @@ -21,6 +21,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import java.io.IOException; import java.util.logging.Logger; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -32,6 +33,7 @@ import org.apache.hc.core5.http.HttpResponse; import org.apache.hc.core5.http.nio.AsyncRequestProducer; import org.apache.hc.core5.http.nio.DataStreamChannel; import org.apache.hc.core5.http.nio.RequestChannel; +import org.apache.hc.core5.http.protocol.BasicHttpContext; import org.apache.hc.core5.http.protocol.HttpContext; import org.apache.hc.core5.http.protocol.HttpCoreContext; @@ -67,10 +69,13 @@ class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation { @Advice.OnMethodEnter(suppress = Throwable.class) public static void methodEnter( @Advice.Argument(value = 0, readOnly = false) AsyncRequestProducer requestProducer, - @Advice.Argument(3) HttpContext httpContext, + @Advice.Argument(value = 3, readOnly = false) HttpContext httpContext, @Advice.Argument(value = 4, readOnly = false) FutureCallback futureCallback) { Context parentContext = currentContext(); + if (httpContext == null) { + httpContext = new BasicHttpContext(); + } WrappedFutureCallback wrappedFutureCallback = new WrappedFutureCallback<>(parentContext, httpContext, futureCallback); @@ -182,7 +187,7 @@ class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation { return; } - instrumenter().end(context, httpRequest, getResponse(httpContext), null); + instrumenter().end(context, httpRequest, getResponseFromHttpContext(), null); if (parentContext == null) { completeDelegate(result); @@ -204,7 +209,7 @@ class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation { } // end span before calling delegate - instrumenter().end(context, httpRequest, getResponse(httpContext), ex); + instrumenter().end(context, httpRequest, getResponseFromHttpContext(), ex); if (parentContext == null) { failDelegate(ex); @@ -227,7 +232,7 @@ class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation { // TODO (trask) add "canceled" span attribute // end span before calling delegate - instrumenter().end(context, httpRequest, getResponse(httpContext), null); + instrumenter().end(context, httpRequest, getResponseFromHttpContext(), null); if (parentContext == null) { cancelDelegate(); @@ -257,8 +262,9 @@ class ApacheHttpAsyncClientInstrumentation implements TypeInstrumentation { } } - private static HttpResponse getResponse(HttpContext context) { - return (HttpResponse) context.getAttribute(HttpCoreContext.HTTP_RESPONSE); + @Nullable + private HttpResponse getResponseFromHttpContext() { + return (HttpResponse) httpContext.getAttribute(HttpCoreContext.HTTP_RESPONSE); } } }