Enable https tests (#3258)

This commit is contained in:
Lauri Tulmin 2021-06-12 03:16:34 +03:00 committed by GitHub
parent 24aa31ebc3
commit de7eaa0fe6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 191 additions and 71 deletions

View File

@ -60,11 +60,6 @@ class AsyncHttpClientTest extends HttpClientTest<Request> implements AgentTestTr
false
}
@Override
boolean testHttps() {
false
}
@Override
SingleConnection createSingleConnection(String host, int port) {
// AsyncHttpClient does not support HTTP 1.1 pipelining nor waiting for connection pool slots to

View File

@ -66,11 +66,6 @@ class AsyncHttpClientTest extends HttpClientTest<Request> implements AgentTestTr
false
}
@Override
boolean testHttps() {
false
}
@Override
Set<AttributeKey<?>> httpAttributes(URI uri) {
Set<AttributeKey<?>> extra = [

View File

@ -34,7 +34,8 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
return;
}
Context context = tracer().startSpan(parentContext, ctx, (HttpRequest) msg);
NettyRequestWrapper requestWrapper = new NettyRequestWrapper((HttpRequest) msg, ctx);
Context context = tracer().startSpan(parentContext, ctx, requestWrapper);
ctx.channel().attr(AttributeKeys.CLIENT_CONTEXT).set(context);
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_CONTEXT).set(parentContext);

View File

@ -15,7 +15,6 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramChannel;
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;
@ -29,7 +28,7 @@ import java.net.URISyntaxException;
import org.checkerframework.checker.nullness.qual.Nullable;
public class NettyHttpClientTracer
extends HttpClientTracer<HttpRequest, HttpHeaders, HttpResponse> {
extends HttpClientTracer<NettyRequestWrapper, HttpHeaders, HttpResponse> {
private static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
private NettyHttpClientTracer() {
@ -40,7 +39,8 @@ public class NettyHttpClientTracer
return TRACER;
}
public Context startSpan(Context parentContext, ChannelHandlerContext ctx, HttpRequest request) {
public Context startSpan(
Context parentContext, ChannelHandlerContext ctx, NettyRequestWrapper request) {
SpanBuilder spanBuilder = spanBuilder(parentContext, spanNameForRequest(request), CLIENT);
onRequest(spanBuilder, request);
NetPeerAttributes.INSTANCE.setNetPeer(
@ -62,24 +62,24 @@ public class NettyHttpClientTracer
}
@Override
protected String method(HttpRequest httpRequest) {
return httpRequest.getMethod().name();
protected String method(NettyRequestWrapper httpRequest) {
return httpRequest.method().name();
}
@Override
@Nullable
protected String flavor(HttpRequest httpRequest) {
return httpRequest.getProtocolVersion().text();
protected String flavor(NettyRequestWrapper httpRequest) {
return httpRequest.protocolVersion().text();
}
@Override
protected URI url(HttpRequest request) throws URISyntaxException {
URI uri = new URI(request.getUri());
protected URI url(NettyRequestWrapper request) throws URISyntaxException {
URI uri = new URI(request.uri());
if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) {
return new URI("http://" + request.headers().get(HOST) + request.getUri());
} else {
return uri;
String protocol = request.isHttps() ? "https://" : "http://";
uri = new URI(protocol + request.headers().get(HOST) + request.uri());
}
return uri;
}
@Override
@ -88,7 +88,7 @@ public class NettyHttpClientTracer
}
@Override
protected String requestHeader(HttpRequest httpRequest, String name) {
protected String requestHeader(NettyRequestWrapper httpRequest, String name) {
return httpRequest.headers().get(name);
}

View File

@ -0,0 +1,62 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.netty.v4_0.client;
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;
public class NettyRequestWrapper {
private static final Class<? extends ChannelHandler> sslHandlerClass = getSslHandlerClass();
@SuppressWarnings("unchecked")
private static Class<? extends ChannelHandler> getSslHandlerClass() {
try {
return (Class<? extends ChannelHandler>)
Class.forName(
"io.netty.handler.ssl.SslHandler",
false,
HttpClientRequestTracingHandler.class.getClassLoader());
} catch (ClassNotFoundException exception) {
return null;
}
}
private final HttpRequest request;
private final ChannelHandlerContext ctx;
public NettyRequestWrapper(HttpRequest request, ChannelHandlerContext ctx) {
this.request = request;
this.ctx = ctx;
}
public HttpRequest request() {
return request;
}
public boolean isHttps() {
return sslHandlerClass != null && ctx.pipeline().get(sslHandlerClass) != null;
}
public HttpHeaders headers() {
return request.headers();
}
public HttpVersion protocolVersion() {
return request.getProtocolVersion();
}
public String uri() {
return request.getUri();
}
public HttpMethod method() {
return request().getMethod();
}
}

View File

@ -27,13 +27,15 @@ import spock.lang.Shared
class Netty40ClientTest extends HttpClientTest<DefaultFullHttpRequest> implements AgentTestTrait {
@Shared
private EventLoopGroup eventLoopGroup = new NioEventLoopGroup()
@Shared
private Bootstrap bootstrap
def setupSpec() {
EventLoopGroup group = new NioEventLoopGroup()
bootstrap = new Bootstrap()
bootstrap.group(group)
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT_MS)
.handler(new ChannelInitializer<SocketChannel>() {
@ -45,6 +47,10 @@ class Netty40ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
})
}
def cleanupSpec() {
eventLoopGroup?.shutdownGracefully()
}
@Override
DefaultFullHttpRequest buildRequest(String method, URI uri, Map<String, String> headers) {
def request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.valueOf(method), uri.toString(), Unpooled.EMPTY_BUFFER)

View File

@ -35,7 +35,8 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
return;
}
Context context = tracer().startSpan(parentContext, ctx, (HttpRequest) msg);
NettyRequestWrapper requestWrapper = new NettyRequestWrapper((HttpRequest) msg, ctx);
Context context = tracer().startSpan(parentContext, ctx, requestWrapper);
Attribute<Context> clientContextAttr = ctx.channel().attr(AttributeKeys.CLIENT_CONTEXT);
Attribute<Context> parentContextAttr = ctx.channel().attr(AttributeKeys.CLIENT_PARENT_CONTEXT);

View File

@ -29,7 +29,7 @@ import java.net.URISyntaxException;
import org.checkerframework.checker.nullness.qual.Nullable;
public class NettyHttpClientTracer
extends HttpClientTracer<HttpRequest, HttpHeaders, HttpResponse> {
extends HttpClientTracer<NettyRequestWrapper, HttpHeaders, HttpResponse> {
private static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
private NettyHttpClientTracer() {
@ -40,7 +40,8 @@ public class NettyHttpClientTracer
return TRACER;
}
public Context startSpan(Context parentContext, ChannelHandlerContext ctx, HttpRequest request) {
public Context startSpan(
Context parentContext, ChannelHandlerContext ctx, NettyRequestWrapper request) {
SpanBuilder spanBuilder = spanBuilder(parentContext, spanNameForRequest(request), CLIENT);
onRequest(spanBuilder, request);
NetPeerAttributes.INSTANCE.setNetPeer(
@ -62,24 +63,24 @@ public class NettyHttpClientTracer
}
@Override
protected String method(HttpRequest httpRequest) {
protected String method(NettyRequestWrapper httpRequest) {
return httpRequest.method().name();
}
@Override
@Nullable
protected String flavor(HttpRequest httpRequest) {
protected String flavor(NettyRequestWrapper httpRequest) {
return httpRequest.protocolVersion().text();
}
@Override
protected URI url(HttpRequest request) throws URISyntaxException {
protected URI url(NettyRequestWrapper request) throws URISyntaxException {
URI uri = new URI(request.uri());
if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) {
return new URI("http://" + request.headers().get(HOST) + request.uri());
} else {
return uri;
String protocol = request.isHttps() ? "https://" : "http://";
uri = new URI(protocol + request.headers().get(HOST) + request.uri());
}
return uri;
}
@Override
@ -88,7 +89,7 @@ public class NettyHttpClientTracer
}
@Override
protected String requestHeader(HttpRequest httpRequest, String name) {
protected String requestHeader(NettyRequestWrapper httpRequest, String name) {
return httpRequest.headers().get(name);
}

View File

@ -0,0 +1,62 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.netty.v4_1.client;
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;
public class NettyRequestWrapper {
private static final Class<? extends ChannelHandler> sslHandlerClass = getSslHandlerClass();
@SuppressWarnings("unchecked")
private static Class<? extends ChannelHandler> getSslHandlerClass() {
try {
return (Class<? extends ChannelHandler>)
Class.forName(
"io.netty.handler.ssl.SslHandler",
false,
HttpClientRequestTracingHandler.class.getClassLoader());
} catch (ClassNotFoundException exception) {
return null;
}
}
private final HttpRequest request;
private final ChannelHandlerContext ctx;
public NettyRequestWrapper(HttpRequest request, ChannelHandlerContext ctx) {
this.request = request;
this.ctx = ctx;
}
public HttpRequest request() {
return request;
}
public boolean isHttps() {
return sslHandlerClass != null && ctx.pipeline().get(sslHandlerClass) != null;
}
public HttpHeaders headers() {
return request.headers();
}
public HttpVersion protocolVersion() {
return request.protocolVersion();
}
public String uri() {
return request.uri();
}
public HttpMethod method() {
return request().method();
}
}

View File

@ -25,6 +25,9 @@ import io.netty.handler.codec.http.HttpClientCodec
import io.netty.handler.codec.http.HttpHeaderNames
import io.netty.handler.codec.http.HttpMethod
import io.netty.handler.codec.http.HttpVersion
import io.netty.handler.ssl.SslContext
import io.netty.handler.ssl.SslContextBuilder
import io.netty.handler.ssl.util.InsecureTrustManagerFactory
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.test.base.HttpClientTest
@ -39,24 +42,39 @@ import spock.lang.Unroll
class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implements AgentTestTrait {
@Shared
private Bootstrap bootstrap
private EventLoopGroup eventLoopGroup = buildEventLoopGroup()
def setupSpec() {
EventLoopGroup group = getEventLoopGroup()
bootstrap = new Bootstrap()
bootstrap.group(group)
@Shared
private Bootstrap bootstrap = buildBootstrap(false)
@Shared
private Bootstrap httpsBootstrap = buildBootstrap(true)
def cleanupSpec() {
eventLoopGroup?.shutdownGracefully()
}
Bootstrap buildBootstrap(boolean https) {
Bootstrap bootstrap = new Bootstrap()
bootstrap.group(eventLoopGroup)
.channel(getChannelClass())
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT_MS)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline()
if (https) {
SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build()
pipeline.addLast(sslContext.newHandler(socketChannel.alloc()))
}
pipeline.addLast(new HttpClientCodec())
}
})
return bootstrap
}
EventLoopGroup getEventLoopGroup() {
EventLoopGroup buildEventLoopGroup() {
return new NioEventLoopGroup()
}
@ -64,6 +82,10 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
return NioSocketChannel
}
Bootstrap getBootstrap(URI uri) {
return uri.getScheme() == "https" ? httpsBootstrap : bootstrap
}
@Override
DefaultFullHttpRequest buildRequest(String method, URI uri, Map<String, String> headers) {
def request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.valueOf(method), uri.toString(), Unpooled.EMPTY_BUFFER)
@ -74,7 +96,7 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
@Override
int sendRequest(DefaultFullHttpRequest request, String method, URI uri, Map<String, String> headers) {
def channel = bootstrap.connect(uri.host, getPort(uri)).sync().channel()
def channel = getBootstrap(uri).connect(uri.host, getPort(uri)).sync().channel()
def result = new CompletableFuture<Integer>()
channel.pipeline().addLast(new ClientHandler(result))
channel.writeAndFlush(request).get()
@ -85,7 +107,7 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
void sendRequestWithCallback(DefaultFullHttpRequest request, String method, URI uri, Map<String, String> headers, RequestResult requestResult) {
Channel ch
try {
ch = bootstrap.connect(uri.host, getPort(uri)).sync().channel()
ch = getBootstrap(uri).connect(uri.host, getPort(uri)).sync().channel()
} catch (Exception exception) {
requestResult.complete(exception)
return
@ -124,11 +146,6 @@ class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implement
false
}
@Override
boolean testHttps() {
false
}
def "test connection reuse and second request with lazy execute"() {
setup:
//Create a simple Netty pipeline

View File

@ -16,7 +16,7 @@ import org.junit.Assume
// netty client test with epoll/kqueue native library
class Netty41NativeClientTest extends Netty41ClientTest {
EventLoopGroup getEventLoopGroup() {
EventLoopGroup buildEventLoopGroup() {
// linux
if (Epoll.isAvailable()) {
return new EpollEventLoopGroup()
@ -28,7 +28,7 @@ class Netty41NativeClientTest extends Netty41ClientTest {
// skip test when native library was not found
Assume.assumeTrue("Native library was not found", false)
return super.getEventLoopGroup()
return super.buildEventLoopGroup()
}
@Override

View File

@ -62,11 +62,6 @@ class PlayWsClientTest extends HttpClientTest<WSRequest> implements AgentTestTra
false
}
@Override
boolean testHttps() {
false
}
@Override
Set<AttributeKey<?>> httpAttributes(URI uri) {
Set<AttributeKey<?>> extra = [

View File

@ -148,9 +148,4 @@ class RatpackHttpClientTest extends HttpClientTest<Void> implements AgentTestTra
// these tests will pass, but they don't really test anything since REQUEST is Void
false
}
@Override
boolean testHttps() {
false
}
}

View File

@ -27,11 +27,6 @@ abstract class AbstractReactorNettyHttpClientTest extends HttpClientTest<HttpCli
false
}
@Override
boolean testHttps() {
false
}
@Override
String userAgent() {
return "ReactorNetty"

View File

@ -32,11 +32,6 @@ abstract class AbstractReactorNettyHttpClientTest extends HttpClientTest<HttpCli
false
}
@Override
boolean testHttps() {
false
}
@Override
String userAgent() {
return "ReactorNetty"