Skip to content

Commit a9af310

Browse files
committed
Rework reading spring web headers
1 parent 5972f4d commit a9af310

File tree

6 files changed

+76
-84
lines changed

6 files changed

+76
-84
lines changed
Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
package io.opentelemetry.instrumentation.spring.webflux.v5_3;
6+
package io.opentelemetry.instrumentation.spring.web.v3_1;
77

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

1010
import java.lang.invoke.MethodHandle;
1111
import java.lang.invoke.MethodHandles;
1212
import java.lang.invoke.MethodType;
1313
import java.util.List;
14+
import java.util.Map;
1415
import javax.annotation.Nullable;
1516
import org.springframework.http.HttpHeaders;
1617

@@ -19,14 +20,7 @@ class HeaderUtil {
1920

2021
static {
2122
// since spring web 7.0
22-
MethodHandle methodHandle =
23-
findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class));
24-
if (methodHandle == null) {
25-
// up to spring web 7.0
26-
methodHandle =
27-
findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class));
28-
}
29-
GET_HEADERS = methodHandle;
23+
GET_HEADERS = findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class));
3024
}
3125

3226
private static MethodHandle findGetHeadersMethod(MethodType methodType) {
@@ -37,9 +31,16 @@ private static MethodHandle findGetHeadersMethod(MethodType methodType) {
3731
}
3832
}
3933

40-
@SuppressWarnings("unchecked") // casting MethodHandle.invoke result
34+
// before spring web 7.0 HttpHeaders implements Map<String, List<String>>, this triggers
35+
// errorprone BadInstanceof warning since errorpone is not aware that this instanceof check does
36+
// not pass with spring web 7.0+
37+
@SuppressWarnings({"unchecked", "BadInstanceof"})
4138
static List<String> getHeader(HttpHeaders headers, String name) {
42-
if (GET_HEADERS != null) {
39+
if (headers instanceof Map) {
40+
// before spring web 7.0
41+
return ((Map<String, List<String>>) headers).getOrDefault(name, emptyList());
42+
} else if (GET_HEADERS != null) {
43+
// spring web 7.0
4344
try {
4445
return (List<String>) GET_HEADERS.invoke(headers, name, emptyList());
4546
} catch (Throwable t) {

instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55

66
package io.opentelemetry.instrumentation.spring.web.v3_1;
77

8-
import static java.util.Collections.emptyList;
9-
108
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter;
119
import java.lang.invoke.MethodHandle;
1210
import java.lang.invoke.MethodHandles;
1311
import java.lang.invoke.MethodType;
1412
import java.util.List;
1513
import javax.annotation.Nullable;
16-
import org.springframework.http.HttpHeaders;
1714
import org.springframework.http.HttpRequest;
1815
import org.springframework.http.client.ClientHttpResponse;
1916

@@ -23,7 +20,6 @@ enum SpringWebHttpAttributesGetter
2320

2421
@Nullable private static final MethodHandle GET_STATUS_CODE;
2522
@Nullable private static final MethodHandle STATUS_CODE_VALUE;
26-
@Nullable private static final MethodHandle GET_HEADERS;
2723

2824
static {
2925
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
@@ -58,24 +54,6 @@ enum SpringWebHttpAttributesGetter
5854

5955
GET_STATUS_CODE = getStatusCode;
6056
STATUS_CODE_VALUE = statusCodeValue;
61-
62-
// since spring web 7.0
63-
MethodHandle methodHandle =
64-
findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class));
65-
if (methodHandle == null) {
66-
// up to spring web 7.0
67-
methodHandle =
68-
findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class));
69-
}
70-
GET_HEADERS = methodHandle;
71-
}
72-
73-
private static MethodHandle findGetHeadersMethod(MethodType methodType) {
74-
try {
75-
return MethodHandles.lookup().findVirtual(HttpHeaders.class, "getOrDefault", methodType);
76-
} catch (Throwable t) {
77-
return null;
78-
}
7957
}
8058

8159
@Override
@@ -91,19 +69,7 @@ public String getUrlFull(HttpRequest httpRequest) {
9169

9270
@Override
9371
public List<String> getHttpRequestHeader(HttpRequest httpRequest, String name) {
94-
return getHeader(httpRequest.getHeaders(), name);
95-
}
96-
97-
@SuppressWarnings("unchecked") // casting MethodHandle.invoke result
98-
private static List<String> getHeader(HttpHeaders headers, String name) {
99-
if (GET_HEADERS != null) {
100-
try {
101-
return (List<String>) GET_HEADERS.invoke(headers, name, emptyList());
102-
} catch (Throwable t) {
103-
// ignore
104-
}
105-
}
106-
return emptyList();
72+
return HeaderUtil.getHeader(httpRequest.getHeaders(), name);
10773
}
10874

10975
@Override
@@ -125,7 +91,7 @@ public Integer getHttpResponseStatusCode(
12591
@Override
12692
public List<String> getHttpResponseHeader(
12793
HttpRequest httpRequest, ClientHttpResponse clientHttpResponse, String name) {
128-
return getHeader(clientHttpResponse.getHeaders(), name);
94+
return HeaderUtil.getHeader(clientHttpResponse.getHeaders(), name);
12995
}
13096

13197
@Override

instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/WebfluxServerHttpAttributesGetter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.instrumentation.spring.webflux.v5_3;
77

88
import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesGetter;
9+
import io.opentelemetry.instrumentation.spring.webflux.v5_3.internal.HeaderUtil;
910
import java.lang.invoke.MethodHandle;
1011
import java.lang.invoke.MethodHandles;
1112
import java.lang.invoke.MethodType;

instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/WebfluxTextMapGetter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import static java.util.Collections.emptyIterator;
99

1010
import io.opentelemetry.context.propagation.TextMapGetter;
11+
import io.opentelemetry.instrumentation.spring.webflux.v5_3.internal.HeaderUtil;
1112
import java.util.Iterator;
1213
import javax.annotation.Nullable;
1314
import org.springframework.web.server.ServerWebExchange;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.spring.webflux.v5_3.internal;
7+
8+
import static java.util.Collections.emptyList;
9+
10+
import java.lang.invoke.MethodHandle;
11+
import java.lang.invoke.MethodHandles;
12+
import java.lang.invoke.MethodType;
13+
import java.util.List;
14+
import java.util.Map;
15+
import javax.annotation.Nullable;
16+
import org.springframework.http.HttpHeaders;
17+
18+
/**
19+
* This class is internal and experimental. Its APIs are unstable and can change at any time. Its
20+
* APIs (or a version of them) may be promoted to the public stable API in the future, but no
21+
* guarantees are made.
22+
*/
23+
public final class HeaderUtil {
24+
@Nullable private static final MethodHandle GET_HEADERS;
25+
26+
static {
27+
// since spring web 7.0
28+
GET_HEADERS = findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class));
29+
}
30+
31+
private static MethodHandle findGetHeadersMethod(MethodType methodType) {
32+
try {
33+
return MethodHandles.lookup().findVirtual(HttpHeaders.class, "getOrDefault", methodType);
34+
} catch (Throwable t) {
35+
return null;
36+
}
37+
}
38+
39+
// before spring web 7.0 HttpHeaders implements Map<String, List<String>>, this triggers
40+
// errorprone BadInstanceof warning since errorpone is not aware that this instanceof check does
41+
// not pass with spring web 7.0+
42+
@SuppressWarnings({"unchecked", "BadInstanceof"})
43+
public static List<String> getHeader(HttpHeaders headers, String name) {
44+
if (headers instanceof Map) {
45+
// before spring web 7.0
46+
return ((Map<String, List<String>>) headers).getOrDefault(name, emptyList());
47+
} else if (GET_HEADERS != null) {
48+
// spring web 7.0
49+
try {
50+
return (List<String>) GET_HEADERS.invoke(headers, name, emptyList());
51+
} catch (Throwable t) {
52+
// ignore
53+
}
54+
}
55+
return emptyList();
56+
}
57+
58+
private HeaderUtil() {}
59+
}

instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,9 @@
55

66
package io.opentelemetry.instrumentation.spring.webflux.v5_3.internal;
77

8-
import static java.util.Collections.emptyList;
9-
108
import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter;
11-
import java.lang.invoke.MethodHandle;
12-
import java.lang.invoke.MethodHandles;
13-
import java.lang.invoke.MethodType;
149
import java.util.List;
1510
import javax.annotation.Nullable;
16-
import org.springframework.http.HttpHeaders;
1711
import org.springframework.web.reactive.function.client.ClientRequest;
1812
import org.springframework.web.reactive.function.client.ClientResponse;
1913

@@ -25,28 +19,6 @@ public enum WebClientHttpAttributesGetter
2519
implements HttpClientAttributesGetter<ClientRequest, ClientResponse> {
2620
INSTANCE;
2721

28-
private static final MethodHandle GET_HEADERS;
29-
30-
static {
31-
// since webflux 7.0
32-
MethodHandle methodHandle =
33-
findGetHeadersMethod(MethodType.methodType(List.class, String.class, List.class));
34-
if (methodHandle == null) {
35-
// up to webflux 7.0
36-
methodHandle =
37-
findGetHeadersMethod(MethodType.methodType(Object.class, Object.class, Object.class));
38-
}
39-
GET_HEADERS = methodHandle;
40-
}
41-
42-
private static MethodHandle findGetHeadersMethod(MethodType methodType) {
43-
try {
44-
return MethodHandles.lookup().findVirtual(HttpHeaders.class, "getOrDefault", methodType);
45-
} catch (Throwable t) {
46-
return null;
47-
}
48-
}
49-
5022
@Override
5123
public String getUrlFull(ClientRequest request) {
5224
return request.url().toString();
@@ -58,16 +30,8 @@ public String getHttpRequestMethod(ClientRequest request) {
5830
}
5931

6032
@Override
61-
@SuppressWarnings("unchecked") // casting MethodHandle.invoke result
6233
public List<String> getHttpRequestHeader(ClientRequest request, String name) {
63-
if (GET_HEADERS != null) {
64-
try {
65-
return (List<String>) GET_HEADERS.invoke(request.headers(), name, emptyList());
66-
} catch (Throwable t) {
67-
// ignore
68-
}
69-
}
70-
return emptyList();
34+
return HeaderUtil.getHeader(request.headers(), name);
7135
}
7236

7337
@Override

0 commit comments

Comments
 (0)