Skip to content

Commit 45e9b8b

Browse files
committed
feat: introduce common helper interface
1 parent f799ac5 commit 45e9b8b

File tree

22 files changed

+236
-223
lines changed

22 files changed

+236
-223
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
plugins {
2+
id("otel.javaagent-instrumentation")
3+
}
4+
5+
dependencies {
6+
compileOnly("com.ning:async-http-client:1.8.3")
7+
8+
compileOnly("com.google.auto.value:auto-value-annotations")
9+
annotationProcessor("com.google.auto.value:auto-value")
10+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_8;
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;
77

88
import com.google.auto.value.AutoValue;
99
import com.ning.http.client.Request;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;
7+
8+
import com.ning.http.client.Request;
9+
import javax.annotation.Nullable;
10+
11+
/**
12+
* Helper interface to abstract away differences between AsyncHttpClient versions.
13+
* This allows sharing common instrumentation code while handling version-specific API differences.
14+
*/
15+
public interface AsyncHttpClientHelper {
16+
17+
/**
18+
* Get the full URL from the request.
19+
*
20+
* @param request the HTTP request
21+
* @return the full URL as a string, or null if it cannot be determined
22+
*/
23+
@Nullable
24+
String getUrlFull(Request request);
25+
26+
/**
27+
* Get the server address (host) from the request.
28+
*
29+
* @param request the HTTP request
30+
* @return the server address
31+
*/
32+
String getServerAddress(Request request);
33+
34+
/**
35+
* Get the server port from the request.
36+
*
37+
* @param request the HTTP request
38+
* @return the server port
39+
*/
40+
Integer getServerPort(Request request);
41+
42+
/**
43+
* Set a header on the request.
44+
*
45+
* @param request the HTTP request
46+
* @param key the header name
47+
* @param value the header value
48+
*/
49+
void setHeader(Request request, String key, String value);
50+
}
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;
77

88
import static java.util.Collections.emptyList;
99

@@ -13,17 +13,23 @@
1313
import java.util.List;
1414
import javax.annotation.Nullable;
1515

16-
final class AsyncHttpClientHttpAttributesGetter
16+
public final class AsyncHttpClientHttpAttributesGetter
1717
implements HttpClientAttributesGetter<Request, Response> {
1818

19+
private final AsyncHttpClientHelper helper;
20+
21+
public AsyncHttpClientHttpAttributesGetter(AsyncHttpClientHelper helper) {
22+
this.helper = helper;
23+
}
24+
1925
@Override
2026
public String getHttpRequestMethod(Request request) {
2127
return request.getMethod();
2228
}
2329

2430
@Override
2531
public String getUrlFull(Request request) {
26-
return request.getUri().toUrl();
32+
return helper.getUrlFull(request);
2733
}
2834

2935
@Override
@@ -44,11 +50,11 @@ public List<String> getHttpResponseHeader(Request request, Response response, St
4450

4551
@Override
4652
public String getServerAddress(Request request) {
47-
return request.getUri().getHost();
53+
return helper.getServerAddress(request);
4854
}
4955

5056
@Override
5157
public Integer getServerPort(Request request) {
52-
return request.getUri().getPort();
58+
return helper.getServerPort(request);
5359
}
5460
}
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_8;
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;
77

88
import com.ning.http.client.Request;
99
import io.opentelemetry.context.propagation.TextMapSetter;
1010

11-
enum HttpHeaderSetter implements TextMapSetter<Request> {
12-
INSTANCE;
11+
public final class HttpHeaderSetter implements TextMapSetter<Request> {
12+
13+
private final AsyncHttpClientHelper helper;
14+
15+
public HttpHeaderSetter(AsyncHttpClientHelper helper) {
16+
this.helper = helper;
17+
}
1318

1419
@Override
1520
public void set(Request carrier, String key, String value) {
16-
carrier.getHeaders().replace(key, value);
21+
helper.setHeader(carrier, key, value);
1722
}
1823
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;
7+
8+
import io.opentelemetry.context.ContextKey;
9+
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
10+
11+
public final class InstrumenterContextKey {
12+
public static final ContextKey<Instrumenter<?, ?>> KEY =
13+
ContextKey.named("async-http-client-instrumenter");
14+
15+
private InstrumenterContextKey() {}
16+
}
Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.common;
77

88
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
9-
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.ASYNC_HANDLER_DATA;
10-
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.instrumenter;
119
import static net.bytebuddy.matcher.ElementMatchers.hasSuperClass;
1210
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
1311
import static net.bytebuddy.matcher.ElementMatchers.named;
1412
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
1513

1614
import com.ning.http.client.AsyncCompletionHandler;
15+
import com.ning.http.client.AsyncHandler;
16+
import com.ning.http.client.Request;
1717
import com.ning.http.client.Response;
1818
import io.opentelemetry.context.Scope;
19+
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
20+
import io.opentelemetry.instrumentation.api.util.VirtualField;
1921
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2022
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
2123
import net.bytebuddy.asm.Advice;
@@ -53,12 +55,21 @@ public static class OnCompletedAdvice {
5355
public static Scope onEnter(
5456
@Advice.This AsyncCompletionHandler<?> handler, @Advice.Argument(0) Response response) {
5557

56-
AsyncHandlerData data = ASYNC_HANDLER_DATA.get(handler);
58+
VirtualField<AsyncHandler<?>, AsyncHandlerData> asyncHandlerDataField =
59+
VirtualField.find(AsyncHandler.class, AsyncHandlerData.class);
60+
AsyncHandlerData data = asyncHandlerDataField.get(handler);
5761
if (data == null) {
5862
return null;
5963
}
60-
ASYNC_HANDLER_DATA.set(handler, null);
61-
instrumenter().end(data.getContext(), data.getRequest(), response, null);
64+
asyncHandlerDataField.set(handler, null);
65+
66+
// Get instrumenter from the data context - we'll store it there
67+
@SuppressWarnings("unchecked")
68+
Instrumenter<Request, Response> instrumenter =
69+
(Instrumenter<Request, Response>) data.getContext().get(InstrumenterContextKey.KEY);
70+
if (instrumenter != null) {
71+
instrumenter.end(data.getContext(), data.getRequest(), response, null);
72+
}
6273
return data.getParentContext().makeCurrent();
6374
}
6475

@@ -77,12 +88,21 @@ public static class OnThrowableAdvice {
7788
public static Scope onEnter(
7889
@Advice.This AsyncCompletionHandler<?> handler, @Advice.Argument(0) Throwable throwable) {
7990

80-
AsyncHandlerData data = ASYNC_HANDLER_DATA.get(handler);
91+
VirtualField<AsyncHandler<?>, AsyncHandlerData> asyncHandlerDataField =
92+
VirtualField.find(AsyncHandler.class, AsyncHandlerData.class);
93+
AsyncHandlerData data = asyncHandlerDataField.get(handler);
8194
if (data == null) {
8295
return null;
8396
}
84-
ASYNC_HANDLER_DATA.set(handler, null);
85-
instrumenter().end(data.getContext(), data.getRequest(), null, throwable);
97+
asyncHandlerDataField.set(handler, null);
98+
99+
// Get instrumenter from the data context - we'll store it there
100+
@SuppressWarnings("unchecked")
101+
Instrumenter<Request, Response> instrumenter =
102+
(Instrumenter<Request, Response>) data.getContext().get(InstrumenterContextKey.KEY);
103+
if (instrumenter != null) {
104+
instrumenter.end(data.getContext(), data.getRequest(), null, throwable);
105+
}
86106
return data.getParentContext().makeCurrent();
87107
}
88108

instrumentation/async-http-client/async-http-client-1.8/javaagent/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ muzzle {
1212
}
1313

1414
dependencies {
15+
implementation(project(":instrumentation:async-http-client:async-http-client-1-common:javaagent"))
16+
1517
library("com.ning:async-http-client:1.8.3")
1618

1719
compileOnly("com.google.auto.value:auto-value-annotations")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_8;
7+
8+
import com.ning.http.client.Request;
9+
import io.opentelemetry.javaagent.instrumentation.asynchttpclient.common.AsyncHttpClientHelper;
10+
import java.net.MalformedURLException;
11+
import javax.annotation.Nullable;
12+
13+
final class AsyncHttpClient18Helper implements AsyncHttpClientHelper {
14+
15+
static final AsyncHttpClient18Helper INSTANCE = new AsyncHttpClient18Helper();
16+
17+
private AsyncHttpClient18Helper() {}
18+
19+
@Override
20+
@Nullable
21+
public String getUrlFull(Request request) {
22+
try {
23+
return request.getURI().toURL().toString();
24+
} catch (MalformedURLException e) {
25+
return null;
26+
}
27+
}
28+
29+
@Override
30+
public String getServerAddress(Request request) {
31+
return request.getOriginalURI().getHost();
32+
}
33+
34+
@Override
35+
public Integer getServerPort(Request request) {
36+
return request.getOriginalURI().getPort();
37+
}
38+
39+
@Override
40+
public void setHeader(Request request, String key, String value) {
41+
request.getHeaders().replace(key, value);
42+
}
43+
}

instrumentation/async-http-client/async-http-client-1.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/asynchttpclient/v1_8/AsyncHttpClientHttpAttributesGetter.java

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)