Skip to content

Commit 84af3be

Browse files
committed
[#10656] Add java 11 httpclient plugin
1 parent 03a2259 commit 84af3be

29 files changed

+1233
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
## Install
3+
```
4+
$ mvnw -P pinpoint-jdk-httpclient-plugin-testweb install -Dmaven.test.skip=true
5+
```
6+
7+
## Run
8+
```
9+
$ mvnw -P pinpoint-jdk-httpclient-plugin-testweb spring-boot:start
10+
```
11+
You can then access here: https://localhost:18443/
12+
13+
## Stop
14+
```
15+
$ mvnw -P pinpoint-jdk-httpclient-plugin-testweb spring-boot:stop
16+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>com.navercorp.pinpoint</groupId>
7+
<artifactId>pinpoint-agent-testweb</artifactId>
8+
<version>3.0.0-SNAPSHOT</version>
9+
</parent>
10+
11+
<artifactId>pinpoint-jdk-httpclient-plugin-testweb</artifactId>
12+
13+
<packaging>jar</packaging>
14+
15+
<properties>
16+
<pinpoint.agent.jvmargument>
17+
${pinpoint.agent.default.jvmargument}
18+
</pinpoint.agent.jvmargument>
19+
<jdk.version>11</jdk.version>
20+
<jdk.home>${env.JAVA_11_HOME}</jdk.home>
21+
</properties>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.springframework.boot</groupId>
26+
<artifactId>spring-boot-starter-webflux</artifactId>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.springframework.boot</groupId>
30+
<artifactId>spring-boot-autoconfigure</artifactId>
31+
</dependency>
32+
<dependency>
33+
<groupId>com.navercorp.pinpoint</groupId>
34+
<artifactId>pinpoint-agent-testweb-commons</artifactId>
35+
</dependency>
36+
</dependencies>
37+
38+
<build>
39+
<plugins>
40+
<plugin>
41+
<groupId>org.springframework.boot</groupId>
42+
<artifactId>spring-boot-maven-plugin</artifactId>
43+
</plugin>
44+
</plugins>
45+
</build>
46+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright 2024 NAVER Corp.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.pinpoint.test.plugin;
18+
19+
import com.pinpoint.test.common.view.ApiLinkPage;
20+
import com.pinpoint.test.common.view.HrefTag;
21+
import org.apache.logging.log4j.LogManager;
22+
import org.apache.logging.log4j.Logger;
23+
import org.springframework.beans.factory.annotation.Autowired;
24+
import org.springframework.web.bind.annotation.GetMapping;
25+
import org.springframework.web.bind.annotation.RestController;
26+
import org.springframework.web.method.HandlerMethod;
27+
import org.springframework.web.reactive.result.method.RequestMappingInfo;
28+
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
29+
import org.springframework.web.server.ServerWebExchange;
30+
import reactor.core.publisher.Mono;
31+
32+
import java.io.IOException;
33+
import java.net.URI;
34+
import java.net.URISyntaxException;
35+
import java.net.http.HttpClient;
36+
import java.net.http.HttpRequest;
37+
import java.net.http.HttpResponse;
38+
import java.util.ArrayList;
39+
import java.util.Arrays;
40+
import java.util.Comparator;
41+
import java.util.List;
42+
import java.util.Map;
43+
import java.util.concurrent.CompletableFuture;
44+
import java.util.stream.Collectors;
45+
46+
@RestController
47+
public class JdkHttpClientPluginController {
48+
private final Logger logger = LogManager.getLogger(this.getClass());
49+
50+
private final RequestMappingHandlerMapping handlerMapping;
51+
52+
@Autowired
53+
public JdkHttpClientPluginController(RequestMappingHandlerMapping handlerMapping) {
54+
this.handlerMapping = handlerMapping;
55+
}
56+
57+
@GetMapping("/")
58+
String welcome() {
59+
Map<RequestMappingInfo, HandlerMethod> handlerMethods = this.handlerMapping.getHandlerMethods();
60+
List<HrefTag> list = new ArrayList<>();
61+
for (RequestMappingInfo info : handlerMethods.keySet()) {
62+
for (String path : info.getDirectPaths()) {
63+
list.add(HrefTag.of(path));
64+
}
65+
}
66+
list.sort(Comparator.comparing(HrefTag::getPath));
67+
return new ApiLinkPage("spring-webflux-plugin-testweb")
68+
.addHrefTag(list)
69+
.build();
70+
}
71+
72+
@GetMapping("/client/get")
73+
public Mono<String> clientGet(ServerWebExchange exchange) throws IOException, InterruptedException {
74+
HttpClient client = HttpClient.newHttpClient();
75+
HttpRequest request = HttpRequest.newBuilder()
76+
.version(HttpClient.Version.HTTP_2)
77+
.uri(URI.create("http://httpbin.org"))
78+
.headers("Accept-Enconding", "gzip, deflate")
79+
.headers("Cookie", "foo-bar")
80+
.build();
81+
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
82+
83+
String responseBody = response.body();
84+
int responseStatusCode = response.statusCode();
85+
86+
return Mono.just(responseStatusCode + " " + responseBody);
87+
}
88+
89+
@GetMapping("/client/retry")
90+
public Mono<String> clientRetry(ServerWebExchange exchange) throws IOException, InterruptedException {
91+
HttpClient client = HttpClient.newHttpClient();
92+
HttpRequest request = HttpRequest.newBuilder()
93+
.version(HttpClient.Version.HTTP_2)
94+
.uri(URI.create("http://naver.com"))
95+
.headers("Accept-Enconding", "gzip, deflate")
96+
.build();
97+
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
98+
99+
String responseBody = response.body();
100+
int responseStatusCode = response.statusCode();
101+
102+
return Mono.just(responseStatusCode + " " + responseBody);
103+
}
104+
105+
@GetMapping("/client/unknown")
106+
public Mono<String> clientUnknown(ServerWebExchange exchange) throws IOException, InterruptedException {
107+
HttpClient client = HttpClient.newHttpClient();
108+
HttpRequest request = HttpRequest.newBuilder()
109+
.version(HttpClient.Version.HTTP_2)
110+
.uri(URI.create("http://fjaklfjkladjfklajlf"))
111+
.headers("Accept-Enconding", "gzip, deflate")
112+
.build();
113+
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
114+
115+
String responseBody = response.body();
116+
int responseStatusCode = response.statusCode();
117+
118+
return Mono.just(responseStatusCode + " " + responseBody);
119+
}
120+
121+
@GetMapping("/client/post")
122+
public Mono<String> clientPost(ServerWebExchange exchange) throws IOException, InterruptedException, URISyntaxException {
123+
HttpClient client = HttpClient.newBuilder()
124+
.version(HttpClient.Version.HTTP_2)
125+
.build();
126+
HttpRequest request = HttpRequest.newBuilder(new URI("http://httpbin.org"))
127+
.version(HttpClient.Version.HTTP_2)
128+
.POST(HttpRequest.BodyPublishers.ofString("Sample Post Request"))
129+
.build();
130+
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
131+
String responseBody = response.body();
132+
133+
return Mono.just(responseBody);
134+
}
135+
136+
@GetMapping("/client/async")
137+
public Mono<String> clientAsync(ServerWebExchange exchange) throws IOException, InterruptedException, URISyntaxException {
138+
HttpClient client = HttpClient.newHttpClient();
139+
URI httpURI = new URI("http://httpbin.org");
140+
HttpRequest request = HttpRequest.newBuilder(httpURI)
141+
.version(HttpClient.Version.HTTP_2)
142+
.build();
143+
CompletableFuture<Void> futureResponse = client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
144+
.thenAccept(resp -> {
145+
System.out.println("Got pushed response " + resp.uri());
146+
System.out.println("Response statuscode: " + resp.statusCode());
147+
System.out.println("Response body: " + resp.body());
148+
});
149+
System.out.println("futureResponse" + futureResponse);
150+
return Mono.just(futureResponse.toString());
151+
}
152+
153+
@GetMapping("/client/multi")
154+
public Mono<String> clientMulti(ServerWebExchange exchange) throws IOException, InterruptedException, URISyntaxException {
155+
HttpClient client = HttpClient.newHttpClient();
156+
List<URI> uris = Arrays.asList(new URI("http://httpbin.org"), new URI("http://google.com"));
157+
List<HttpRequest> requests = uris.stream()
158+
.map(HttpRequest::newBuilder)
159+
.map(reqBuilder -> reqBuilder.build())
160+
.collect(Collectors.toList());
161+
System.out.println("Got pushed response1 " + requests);
162+
CompletableFuture.allOf(requests.stream()
163+
.map(request -> client.sendAsync(request, HttpResponse.BodyHandlers.ofString()))
164+
.toArray(CompletableFuture<?>[]::new))
165+
.thenAccept(System.out::println)
166+
.join();
167+
return Mono.just("OK");
168+
}
169+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2024 NAVER Corp.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.pinpoint.test.plugin;
18+
19+
import org.springframework.boot.SpringApplication;
20+
import org.springframework.boot.autoconfigure.SpringBootApplication;
21+
22+
@SpringBootApplication
23+
public class JdkHttpClientPluginTestStarter {
24+
25+
public static void main(String[] args) {
26+
SpringApplication.run(JdkHttpClientPluginTestStarter.class, args);
27+
}
28+
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Defined in commandlineArgument of agent-test pom.xml
2+
3+
server:
4+
port: 18080
5+
6+
logging:
7+
level:
8+
root: info
9+
10+
springdoc:
11+
swagger-ui:
12+
path: /

agent-testweb/pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<module>spring-cloud-gateway-plugin-testweb</module>
6363
<module>spring-webflux-plugin-testweb</module>
6464
<module>jdk-http-plugin-testweb</module>
65+
<module>jdk-httpclient-plugin-testweb</module>
6566
<module>vertx-3-plugin-testweb</module>
6667
<module>vertx-4-plugin-testweb</module>
6768
<module>mongodb-plugin-testweb</module>

agent/src/main/resources/profiles/local/pinpoint.config

+23
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,29 @@ profiler.apache.httpclient5.entity.statuscode=true
908908
profiler.jdk.http=true
909909
profiler.jdk.http.param=true
910910

911+
# Java 11 version or later
912+
profiler.jdk.httpclient.enable=true
913+
profiler.jdk.httpclient.param=true
914+
915+
# Record cookies.
916+
profiler.jdk.httpclient.cookie=true
917+
# When to dump cookies. Either ALWAYS or EXCEPTION.
918+
profiler.jdk.httpclient.cookie.dumptype=ALWAYS
919+
# 1 out of n cookies will be sampled where n is the rate. (1: 100%)
920+
profiler.jdk.httpclient.cookie.sampling.rate=1
921+
# Cookie dump size.
922+
profiler.jdk.httpclient.cookie.dumpsize=1024
923+
924+
# Record Entities.
925+
profiler.jdk.httpclient.entity=true
926+
# When to dump entities. Either ALWAYS or EXCEPTION.
927+
profiler.jdk.httpclient.entity.dumptype=ALWAYS
928+
# 1 out of n cookies will be sampled where n is the rate. (1: 100%)
929+
profiler.jdk.httpclient.entity.sampling.rate=1
930+
# Entity dump size.
931+
profiler.jdk.httpclient.entity.dumpsize=1024
932+
933+
911934
###########################################################
912935
# Ning Async HTTP Client #
913936
###########################################################

agent/src/main/resources/profiles/release/pinpoint.config

+22
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,28 @@ profiler.apache.httpclient5.entity.statuscode=true
905905
profiler.jdk.http=true
906906
profiler.jdk.http.param=true
907907

908+
# Java 11 version or later
909+
profiler.jdk.httpclient.enable=true
910+
profiler.jdk.httpclient.param=true
911+
912+
# Record cookies.
913+
profiler.jdk.httpclient.cookie=false
914+
# When to dump cookies. Either ALWAYS or EXCEPTION.
915+
profiler.jdk.httpclient.cookie.dumptype=EXCEPTION
916+
# 1 out of n cookies will be sampled where n is the rate. (1: 100%)
917+
profiler.jdk.httpclient.cookie.sampling.rate=1
918+
# Cookie dump size.
919+
profiler.jdk.httpclient.cookie.dumpsize=1024
920+
921+
# Record Entities.
922+
profiler.jdk.httpclient.entity=false
923+
# When to dump entities. Either ALWAYS or EXCEPTION.
924+
profiler.jdk.httpclient.entity.dumptype=EXCEPTION
925+
# 1 out of n cookies will be sampled where n is the rate. (1: 100%)
926+
profiler.jdk.httpclient.entity.sampling.rate=1
927+
# Entity dump size.
928+
profiler.jdk.httpclient.entity.dumpsize=1024
929+
908930
###########################################################
909931
# Ning Async HTTP Client #
910932
###########################################################

commons/src/main/java/com/navercorp/pinpoint/common/trace/ServiceType.java

+2
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@
248248
* <tr><td>9060</td><td><i>RESERVED</i></td></tr>
249249
* <tr><td>9062</td><td><i>HTTP_CLIENT_5</i></td></tr>
250250
* <tr><td>9063</td><td><i>HTTP_CLIENT_5_INTERNAL</i></td></tr>
251+
* <tr><td>9065</td><td><i>JDK_HTTP_CLIENT</i></td></tr>
252+
* <tr><td>9066</td><td><i>JDK_HTTP_CLIENT_INTERNAL</i></td></tr>
251253
* <tr><td>9070</td><td><i>RESERVED</i></td></tr>
252254
* <tr><td><s>9080</s></td><td><s>APACHE_CXF_CLIENT</s></td></tr>
253255
* <tr><td>9081</td><td>APACHE_CXF_SERVICE_INVOKER</td></tr>

plugins/assembly/pom.xml

+5
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@
136136
<artifactId>pinpoint-jdk-http-plugin</artifactId>
137137
<version>${project.version}</version>
138138
</dependency>
139+
<dependency>
140+
<groupId>com.navercorp.pinpoint</groupId>
141+
<artifactId>pinpoint-jdk-httpclient-plugin</artifactId>
142+
<version>${project.version}</version>
143+
</dependency>
139144
<dependency>
140145
<groupId>com.navercorp.pinpoint</groupId>
141146
<artifactId>pinpoint-redis-plugin</artifactId>

plugins/jdk-completable-future/src/main/java/com/navercorp/pinpoint/plugin/jdk/completable/JdkCompletableFuturePlugin.java

-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ public static class CompletableFutureTransform implements TransformCallback {
6363
public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException {
6464
final InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer);
6565
target.addField(AsyncContextAccessor.class);
66-
67-
6866
for (InstrumentMethod method : target.getDeclaredMethods(MethodFilters.name("complete", "join", "cancel", "get"))) {
6967
method.addInterceptor(CompletableFutureMethodInterceptor.class);
7068
}

plugins/jdk-httpclient/README.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## JDK HttpClient
2+
* Since: Pinpoint 3.0.0
3+
* Range: java [11,]
4+
5+
### Pinpoint Configuration
6+
pinpoint.config
7+
8+
#### HttpClient options.
9+
~~~
10+
# Profile parameter.
11+
profiler.jdk.httpclient.enable=true
12+
profiler.jdk.httpclient.param=true
13+
profiler.jdk.httpclient.cookie=false
14+
profiler.jdk.httpclient.cookie.dumptype=DumpType.EXCEPTION
15+
profiler.jdk.httpclient.cookie.sampling.rate=1
16+
profiler.jdk.httpclient.cookie.dumpsize=1024
17+
profiler.jdk.httpclient.entity=false
18+
profiler.jdk.httpclient.entity.dumptype=DumpType.EXCEPTION
19+
profiler.jdk.httpclient.entity.sampling.rate=1
20+
profiler.jdk.httpclient.entity.dumpsize=1024
21+
~~~

0 commit comments

Comments
 (0)