Move common code from netty 4.0 and 4.1 http client to common superclass
MODIFY
instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/AbstractNettyHttpClientTracer.java
instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/AbstractNettyHttpClientTracer.java
package io.opentelemetry.javaagent.instrumentation.netty.common.client;
import static io.opentelemetry.api.trace.SpanKind.CLIENT;
+import static io.opentelemetry.javaagent.instrumentation.netty.common.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_UDP;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramChannel;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;
@@ -18,18 +20,70 @@ import io.netty.util.concurrent.Future;
import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
+import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.checkerframework.checker.nullness.qual.Nullable;
-public abstract class AbstractNettyHttpClientTracer<REQUEST>
+public abstract class AbstractNettyHttpClientTracer<REQUEST extends AbstractNettyRequestWrapper>
extends HttpClientTracer<REQUEST, HttpHeaders, HttpResponse> {
protected AbstractNettyHttpClientTracer() {
super(NetPeerAttributes.INSTANCE);
}
+ public Context startSpan(Context parentContext, ChannelHandlerContext ctx, REQUEST request) {
+ SpanBuilder spanBuilder = spanBuilder(parentContext, spanNameForRequest(request), CLIENT);
+ onRequest(spanBuilder, request);
+ NetPeerAttributes.INSTANCE.setNetPeer(
+ spanBuilder, (InetSocketAddress) ctx.channel().remoteAddress());
+
+ Context context = withClientSpan(parentContext, spanBuilder.startSpan());
+ inject(context, request.headers(), SETTER);
+ return context;
+ }
+
+ @Override
+ protected String method(REQUEST httpRequest) {
+ return httpRequest.method().name();
+ }
+
+ @Override
+ @Nullable
+ protected String flavor(REQUEST httpRequest) {
+ return httpRequest.protocolVersion().text();
+ }
+
+ @Override
+ protected URI url(REQUEST request) throws URISyntaxException {
+ URI uri = new URI(request.uri());
+ String hostHeader = request.getHostHeader();
+ if ((uri.getHost() == null || uri.getHost().equals("")) && hostHeader != null) {
+ String protocol = request.isHttps() ? "https://" : "http://";
+ uri = new URI(protocol + hostHeader + request.uri());
+ }
+ return uri;
+ }
+
+ @Override
+ protected String requestHeader(AbstractNettyRequestWrapper httpRequest, String name) {
+ return httpRequest.headers().get(name);
+ }
+
+ @Override
+ protected String responseHeader(HttpResponse httpResponse, String name) {
+ return httpResponse.headers().get(name);
+ }
+
+ @Override
+ protected TextMapSetter<HttpHeaders> getSetter() {
+ return SETTER;
+ }
+
public static void operationComplete(Future<?> future) {
AbstractNettyHttpClientTracer tracer = NettyHttpClientTracerAccess.getTracer();
if (tracer == null) {

ADD
instrumentation/netty/netty-4-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/client/AbstractNettyRequestWrapper.java
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package io.opentelemetry.javaagent.instrumentation.netty.common.client;
+
+import io.netty.handler.codec.http.HttpHeaders;
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.HttpRequest;
+import io.netty.handler.codec.http.HttpVersion;
+
+public abstract class AbstractNettyRequestWrapper {
+
+ protected final HttpRequest request;
+
+ protected AbstractNettyRequestWrapper(HttpRequest request) {
+ this.request = request;
+ }
+
+ public final HttpRequest request() {
+ return request;
+ }
+
+ public final HttpHeaders headers() {
+ return request.headers();
+ }
+
+ public abstract boolean isHttps();
+
+ public abstract String getHostHeader();
+
+ public abstract HttpVersion protocolVersion();
+
+ public abstract String uri();
+
+ public abstract HttpMethod method();
+}

MODIFY
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/client/NettyHttpClientTracer.java
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/client/NettyHttpClientTracer.java
package io.opentelemetry.javaagent.instrumentation.netty.v4_0.client;
-import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
-import static io.opentelemetry.api.trace.SpanKind.CLIENT;
-import static io.opentelemetry.javaagent.instrumentation.netty.common.client.NettyResponseInjectAdapter.SETTER;
-
import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponse;
-import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.context.Context;
-import io.opentelemetry.context.propagation.TextMapSetter;
-import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
import io.opentelemetry.javaagent.instrumentation.netty.common.client.AbstractNettyHttpClientTracer;
import io.opentelemetry.javaagent.instrumentation.netty.common.client.NettyHttpClientTracerAccess;
import io.opentelemetry.javaagent.instrumentation.netty.v4_0.AttributeKeys;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import org.checkerframework.checker.nullness.qual.Nullable;
public class NettyHttpClientTracer extends AbstractNettyHttpClientTracer<NettyRequestWrapper> {
private static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
@@ -38,64 +25,16 @@ public class NettyHttpClientTracer extends AbstractNettyHttpClientTracer<NettyRe
return TRACER;
}
- public Context startSpan(
- Context parentContext, ChannelHandlerContext ctx, NettyRequestWrapper request) {
- SpanBuilder spanBuilder = spanBuilder(parentContext, spanNameForRequest(request), CLIENT);
- onRequest(spanBuilder, request);
- NetPeerAttributes.INSTANCE.setNetPeer(
- spanBuilder, (InetSocketAddress) ctx.channel().remoteAddress());
-
- Context context = withClientSpan(parentContext, spanBuilder.startSpan());
- inject(context, request.headers(), SETTER);
- return context;
- }
-
@Override
protected Context getAndRemoveConnectContext(ChannelFuture channelFuture) {
return channelFuture.channel().attr(AttributeKeys.CONNECT_CONTEXT).getAndRemove();
}
- @Override
- protected String method(NettyRequestWrapper httpRequest) {
- return httpRequest.method().name();
- }
-
- @Override
- @Nullable
- protected String flavor(NettyRequestWrapper httpRequest) {
- return httpRequest.protocolVersion().text();
- }
-
- @Override
- protected URI url(NettyRequestWrapper request) throws URISyntaxException {
- URI uri = new URI(request.uri());
- if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) {
- String protocol = request.isHttps() ? "https://" : "http://";
- uri = new URI(protocol + request.headers().get(HOST) + request.uri());
- }
- return uri;
- }
-
@Override
protected Integer status(HttpResponse httpResponse) {
return httpResponse.getStatus().code();
}
- @Override
- protected String requestHeader(NettyRequestWrapper httpRequest, String name) {
- return httpRequest.headers().get(name);
- }
-
- @Override
- protected String responseHeader(HttpResponse httpResponse, String name) {
- return httpResponse.headers().get(name);
- }
-
- @Override
- protected TextMapSetter<HttpHeaders> getSetter() {
- return SETTER;
- }
-
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.netty-4.0";

MODIFY
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/client/NettyRequestWrapper.java
instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/client/NettyRequestWrapper.java
package io.opentelemetry.javaagent.instrumentation.netty.v4_0.client;
+import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
+
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion;
+import io.opentelemetry.javaagent.instrumentation.netty.common.client.AbstractNettyRequestWrapper;
-public class NettyRequestWrapper {
+public class NettyRequestWrapper extends AbstractNettyRequestWrapper {
private static final Class<? extends ChannelHandler> sslHandlerClass = getSslHandlerClass();
@SuppressWarnings("unchecked")
@@ -28,34 +30,34 @@ public class NettyRequestWrapper {
}
}
- private final HttpRequest request;
private final ChannelHandlerContext ctx;
public NettyRequestWrapper(HttpRequest request, ChannelHandlerContext ctx) {
- this.request = request;
+ super(request);
this.ctx = ctx;
}
- public HttpRequest request() {
- return request;
- }
-
+ @Override
public boolean isHttps() {
return sslHandlerClass != null && ctx.pipeline().get(sslHandlerClass) != null;
}
- public HttpHeaders headers() {
- return request.headers();
+ @Override
+ public String getHostHeader() {
+ return request.headers().get(HOST);
}
+ @Override
public HttpVersion protocolVersion() {
return request.getProtocolVersion();
}
+ @Override
public String uri() {
return request.getUri();
}
+ @Override
public HttpMethod method() {
return request().getMethod();
}

MODIFY
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/client/NettyHttpClientTracer.java
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/client/NettyHttpClientTracer.java
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
-import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
-import static io.opentelemetry.api.trace.SpanKind.CLIENT;
-import static io.opentelemetry.javaagent.instrumentation.netty.common.client.NettyResponseInjectAdapter.SETTER;
-
import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
-import io.opentelemetry.api.trace.SpanBuilder;
import io.opentelemetry.context.Context;
-import io.opentelemetry.context.propagation.TextMapSetter;
-import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
import io.opentelemetry.instrumentation.netty.v4_1.AttributeKeys;
import io.opentelemetry.javaagent.instrumentation.netty.common.client.AbstractNettyHttpClientTracer;
import io.opentelemetry.javaagent.instrumentation.netty.common.client.NettyHttpClientTracerAccess;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import org.checkerframework.checker.nullness.qual.Nullable;
public class NettyHttpClientTracer extends AbstractNettyHttpClientTracer<NettyRequestWrapper> {
private static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
@@ -39,64 +26,16 @@ public class NettyHttpClientTracer extends AbstractNettyHttpClientTracer<NettyRe
return TRACER;
}
- public Context startSpan(
- Context parentContext, ChannelHandlerContext ctx, NettyRequestWrapper request) {
- SpanBuilder spanBuilder = spanBuilder(parentContext, spanNameForRequest(request), CLIENT);
- onRequest(spanBuilder, request);
- NetPeerAttributes.INSTANCE.setNetPeer(
- spanBuilder, (InetSocketAddress) ctx.channel().remoteAddress());
-
- Context context = withClientSpan(parentContext, spanBuilder.startSpan());
- inject(context, request.headers(), SETTER);
- return context;
- }
-
@Override
protected Context getAndRemoveConnectContext(ChannelFuture channelFuture) {
return channelFuture.channel().attr(AttributeKeys.CONNECT_CONTEXT).getAndRemove();
}
- @Override
- protected String method(NettyRequestWrapper httpRequest) {
- return httpRequest.method().name();
- }
-
- @Override
- @Nullable
- protected String flavor(NettyRequestWrapper httpRequest) {
- return httpRequest.protocolVersion().text();
- }
-
- @Override
- protected URI url(NettyRequestWrapper request) throws URISyntaxException {
- URI uri = new URI(request.uri());
- if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) {
- String protocol = request.isHttps() ? "https://" : "http://";
- uri = new URI(protocol + request.headers().get(HOST) + request.uri());
- }
- return uri;
- }
-
@Override
protected Integer status(HttpResponse httpResponse) {
return httpResponse.status().code();
}
- @Override
- protected String requestHeader(NettyRequestWrapper httpRequest, String name) {
- return httpRequest.headers().get(name);
- }
-
- @Override
- protected String responseHeader(HttpResponse httpResponse, String name) {
- return httpResponse.headers().get(name);
- }
-
- @Override
- protected TextMapSetter<HttpHeaders> getSetter() {
- return SETTER;
- }
-
public boolean shouldStartSpan(Context parentContext, HttpRequest request) {
if (!super.shouldStartSpan(parentContext)) {
return false;

MODIFY
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/client/NettyRequestWrapper.java
instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/client/NettyRequestWrapper.java
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
+import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
+
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpVersion;
+import io.opentelemetry.javaagent.instrumentation.netty.common.client.AbstractNettyRequestWrapper;
-public class NettyRequestWrapper {
+public class NettyRequestWrapper extends AbstractNettyRequestWrapper {
private static final Class<? extends ChannelHandler> sslHandlerClass = getSslHandlerClass();
@SuppressWarnings("unchecked")
@@ -28,34 +30,34 @@ public class NettyRequestWrapper {
}
}
- private final HttpRequest request;
private final ChannelHandlerContext ctx;
public NettyRequestWrapper(HttpRequest request, ChannelHandlerContext ctx) {
- this.request = request;
+ super(request);
this.ctx = ctx;
}
- public HttpRequest request() {
- return request;
- }
-
+ @Override
public boolean isHttps() {
return sslHandlerClass != null && ctx.pipeline().get(sslHandlerClass) != null;
}
- public HttpHeaders headers() {
- return request.headers();
+ @Override
+ public String getHostHeader() {
+ return request.headers().get(HOST);
}
+ @Override
public HttpVersion protocolVersion() {
return request.protocolVersion();
}
+ @Override
public String uri() {
return request.uri();
}
+ @Override
public HttpMethod method() {
return request().method();
}

Move common code from netty 4.0 and 4.1 http client to common superclass (#3660)