|
16 | 16 |
|
17 | 17 | package io.opentelemetry.javaagent.instrumentation.hypertrace.jaxrs.v2_0;
|
18 | 18 |
|
19 |
| -import io.opentelemetry.api.trace.Span; |
20 |
| -import io.opentelemetry.sdk.trace.data.SpanData; |
21 |
| -import java.io.IOException; |
22 |
| -import java.io.OutputStream; |
23 |
| -import java.lang.annotation.Annotation; |
24 |
| -import java.lang.reflect.Type; |
25 |
| -import java.util.List; |
26 |
| -import java.util.concurrent.ExecutionException; |
27 |
| -import java.util.concurrent.Future; |
28 |
| -import java.util.concurrent.TimeoutException; |
29 |
| -import javax.ws.rs.WebApplicationException; |
| 19 | +import java.util.Map; |
30 | 20 | import javax.ws.rs.client.Client;
|
31 | 21 | import javax.ws.rs.client.ClientBuilder;
|
32 | 22 | import javax.ws.rs.client.Entity;
|
33 |
| -import javax.ws.rs.client.WebTarget; |
| 23 | +import javax.ws.rs.client.Invocation; |
34 | 24 | import javax.ws.rs.core.MediaType;
|
35 |
| -import javax.ws.rs.core.MultivaluedHashMap; |
36 |
| -import javax.ws.rs.core.MultivaluedMap; |
37 |
| -import javax.ws.rs.core.Response; |
38 |
| -import javax.ws.rs.ext.MessageBodyWriter; |
39 |
| -import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes; |
40 |
| -import org.hypertrace.agent.testing.AbstractInstrumenterTest; |
41 |
| -import org.hypertrace.agent.testing.TestHttpServer; |
42 |
| -import org.hypertrace.agent.testing.TestHttpServer.GetJsonHandler; |
43 |
| -import org.junit.jupiter.api.AfterAll; |
44 |
| -import org.junit.jupiter.api.Assertions; |
45 |
| -import org.junit.jupiter.api.BeforeAll; |
46 |
| -import org.junit.jupiter.api.Test; |
47 |
| - |
48 |
| -public class JaxrsClientBodyInstrumentationTest extends AbstractInstrumenterTest { |
49 |
| - |
50 |
| - private static final String JSON = "{\"id\":1,\"name\":\"John\"}"; |
51 |
| - private static final TestHttpServer testHttpServer = new TestHttpServer(); |
52 |
| - |
53 |
| - @BeforeAll |
54 |
| - public static void startServer() throws Exception { |
55 |
| - testHttpServer.start(); |
56 |
| - } |
| 25 | +import org.hypertrace.agent.testing.AbstractHttpClientTest; |
57 | 26 |
|
58 |
| - @AfterAll |
59 |
| - public static void closeServer() throws Exception { |
60 |
| - testHttpServer.close(); |
61 |
| - } |
| 27 | +public class JaxrsClientBodyInstrumentationTest extends AbstractHttpClientTest { |
62 | 28 |
|
63 |
| - @Test |
64 |
| - public void getJson() throws TimeoutException, InterruptedException { |
65 |
| - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); |
66 |
| - Client client = clientBuilder.build(); |
67 |
| - |
68 |
| - Response response = |
69 |
| - client |
70 |
| - .target(String.format("http://localhost:%d/get_json", testHttpServer.port())) |
71 |
| - .request() |
72 |
| - .header("test-request-header", "test-header-value") |
73 |
| - .get(); |
74 |
| - assertGetJson(response); |
75 |
| - } |
| 29 | + private static final Client client = ClientBuilder.newBuilder().build(); |
76 | 30 |
|
77 |
| - @Test |
78 |
| - public void getJsonAsync() throws TimeoutException, InterruptedException, ExecutionException { |
79 |
| - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); |
80 |
| - Client client = clientBuilder.build(); |
81 |
| - |
82 |
| - Future<Response> responseFuture = |
83 |
| - client |
84 |
| - .target(String.format("http://localhost:%d/get_json", testHttpServer.port())) |
85 |
| - .request() |
86 |
| - .header("test-request-header", "test-header-value") |
87 |
| - .async() |
88 |
| - .get(); |
89 |
| - |
90 |
| - Response response = responseFuture.get(); |
91 |
| - assertGetJson(response); |
| 31 | + public JaxrsClientBodyInstrumentationTest() { |
| 32 | + super(true); |
92 | 33 | }
|
93 | 34 |
|
94 |
| - public void assertGetJson(Response response) throws TimeoutException, InterruptedException { |
95 |
| - Assertions.assertEquals(200, response.getStatus()); |
96 |
| - // read entity has to happen before response.close() |
97 |
| - String entity = response.readEntity(String.class); |
98 |
| - Assertions.assertEquals(GetJsonHandler.RESPONSE_BODY, entity); |
99 |
| - Assertions.assertEquals(false, Span.current().isRecording()); |
100 |
| - response.close(); |
101 |
| - |
102 |
| - TEST_WRITER.waitForTraces(1); |
103 |
| - List<List<SpanData>> traces = TEST_WRITER.getTraces(); |
104 |
| - Assertions.assertEquals(1, traces.size()); |
105 |
| - Assertions.assertEquals(2, traces.get(0).size()); |
106 |
| - SpanData clientSpan = traces.get(0).get(0); |
107 |
| - |
108 |
| - Assertions.assertEquals( |
109 |
| - "test-value", |
110 |
| - clientSpan |
111 |
| - .getAttributes() |
112 |
| - .get(HypertraceSemanticAttributes.httpResponseHeader("test-response-header"))); |
113 |
| - Assertions.assertEquals( |
114 |
| - "test-header-value", |
115 |
| - clientSpan |
116 |
| - .getAttributes() |
117 |
| - .get(HypertraceSemanticAttributes.httpRequestHeader("test-request-header"))); |
118 |
| - Assertions.assertNull( |
119 |
| - clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_REQUEST_BODY)); |
120 |
| - SpanData responseBodySpan = traces.get(0).get(1); |
121 |
| - Assertions.assertEquals( |
122 |
| - GetJsonHandler.RESPONSE_BODY, |
123 |
| - responseBodySpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_RESPONSE_BODY)); |
124 |
| - } |
| 35 | + @Override |
| 36 | + public AbstractHttpClientTest.Response doPostRequest( |
| 37 | + String uri, Map<String, String> headers, String body, String contentType) { |
125 | 38 |
|
126 |
| - @Test |
127 |
| - public void postJson() throws TimeoutException, InterruptedException { |
128 |
| - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); |
129 |
| - Client client = clientBuilder.build(); |
130 |
| - |
131 |
| - MyDto myDto = new MyDto(); |
132 |
| - myDto.name = "foo"; |
133 |
| - |
134 |
| - Response response = |
135 |
| - client |
136 |
| - .target(String.format("http://localhost:%d/post", testHttpServer.port())) |
137 |
| - .request() |
138 |
| - .header("test-request-header", "test-header-value") |
139 |
| - .post(Entity.entity(JSON, MediaType.APPLICATION_JSON_TYPE)); |
140 |
| - Assertions.assertEquals(204, response.getStatus()); |
141 |
| - |
142 |
| - TEST_WRITER.waitForTraces(1); |
143 |
| - List<List<SpanData>> traces = TEST_WRITER.getTraces(); |
144 |
| - Assertions.assertEquals(1, traces.size()); |
145 |
| - Assertions.assertEquals(1, traces.get(0).size()); |
146 |
| - SpanData clientSpan = traces.get(0).get(0); |
147 |
| - |
148 |
| - Assertions.assertEquals( |
149 |
| - "test-value", |
150 |
| - clientSpan |
151 |
| - .getAttributes() |
152 |
| - .get(HypertraceSemanticAttributes.httpResponseHeader("test-response-header"))); |
153 |
| - Assertions.assertEquals( |
154 |
| - JSON, clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_REQUEST_BODY)); |
155 |
| - Assertions.assertNull( |
156 |
| - clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_RESPONSE_BODY)); |
157 |
| - } |
| 39 | + Invocation.Builder builder = client.target(uri).request(); |
158 | 40 |
|
159 |
| - @Test |
160 |
| - public void postJsonDtoAsync() throws TimeoutException, InterruptedException, ExecutionException { |
161 |
| - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); |
162 |
| - Client client = clientBuilder.register(MyDtoMessageBodyWriter.class).build(); |
163 |
| - |
164 |
| - MyDto myDto = new MyDto(); |
165 |
| - myDto.name = "name"; |
166 |
| - |
167 |
| - Future<Response> post = |
168 |
| - client |
169 |
| - .target(String.format("http://localhost:%d/post", testHttpServer.port())) |
170 |
| - .request() |
171 |
| - .header("test-request-header", "test-header-value") |
172 |
| - .async() |
173 |
| - .post(Entity.json(myDto)); |
174 |
| - Response response = post.get(); |
175 |
| - Assertions.assertEquals(204, response.getStatus()); |
176 |
| - |
177 |
| - TEST_WRITER.waitForTraces(1); |
178 |
| - List<List<SpanData>> traces = TEST_WRITER.getTraces(); |
179 |
| - Assertions.assertEquals(1, traces.size()); |
180 |
| - Assertions.assertEquals(1, traces.get(0).size()); |
181 |
| - SpanData clientSpan = traces.get(0).get(0); |
182 |
| - |
183 |
| - Assertions.assertEquals( |
184 |
| - "test-value", |
185 |
| - clientSpan |
186 |
| - .getAttributes() |
187 |
| - .get(HypertraceSemanticAttributes.httpResponseHeader("test-response-header"))); |
188 |
| - Assertions.assertEquals( |
189 |
| - myDto.getJson(), |
190 |
| - clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_REQUEST_BODY)); |
191 |
| - Assertions.assertNull( |
192 |
| - clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_RESPONSE_BODY)); |
193 |
| - } |
| 41 | + for (Map.Entry<String, String> entry : headers.entrySet()) { |
| 42 | + builder = builder.header(entry.getKey(), entry.getValue()); |
| 43 | + } |
| 44 | + |
| 45 | + javax.ws.rs.core.Response response = |
| 46 | + builder.post(Entity.entity(body, MediaType.valueOf(contentType))); |
194 | 47 |
|
195 |
| - @Test |
196 |
| - public void postUrlEncoded() throws TimeoutException, InterruptedException { |
197 |
| - ClientBuilder clientBuilder = ClientBuilder.newBuilder(); |
198 |
| - Client client = clientBuilder.build(); |
199 |
| - |
200 |
| - WebTarget webTarget = |
201 |
| - client.target(String.format("http://localhost:%d/post", testHttpServer.port())); |
202 |
| - MultivaluedMap<String, String> formData = new MultivaluedHashMap<>(); |
203 |
| - formData.add("key1", "value1"); |
204 |
| - formData.add("key2", "value2"); |
205 |
| - Response response = webTarget.request().post(Entity.form(formData)); |
206 |
| - Assertions.assertEquals(204, response.getStatus()); |
207 |
| - |
208 |
| - TEST_WRITER.waitForTraces(1); |
209 |
| - List<List<SpanData>> traces = TEST_WRITER.getTraces(); |
210 |
| - Assertions.assertEquals(1, traces.size()); |
211 |
| - Assertions.assertEquals(1, traces.get(0).size()); |
212 |
| - SpanData clientSpan = traces.get(0).get(0); |
213 |
| - |
214 |
| - Assertions.assertEquals( |
215 |
| - "test-value", |
216 |
| - clientSpan |
217 |
| - .getAttributes() |
218 |
| - .get(HypertraceSemanticAttributes.httpResponseHeader("test-response-header"))); |
219 |
| - Assertions.assertEquals( |
220 |
| - "key1=value1&key2=value2", |
221 |
| - clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_REQUEST_BODY)); |
222 |
| - Assertions.assertNull( |
223 |
| - clientSpan.getAttributes().get(HypertraceSemanticAttributes.HTTP_RESPONSE_BODY)); |
| 48 | + return new Response(response.readEntity(String.class), response.getStatus()); |
224 | 49 | }
|
225 | 50 |
|
226 |
| - public static class MyDto { |
227 |
| - public String name; |
| 51 | + @Override |
| 52 | + public AbstractHttpClientTest.Response doGetRequest(String uri, Map<String, String> headers) { |
| 53 | + |
| 54 | + Invocation.Builder builder = client.target(uri).request(); |
228 | 55 |
|
229 |
| - public String getJson() { |
230 |
| - return "{name:\"" + name + "\"}"; |
| 56 | + for (Map.Entry<String, String> entry : headers.entrySet()) { |
| 57 | + builder = builder.header(entry.getKey(), entry.getValue()); |
231 | 58 | }
|
232 |
| - } |
233 | 59 |
|
234 |
| - public static class MyDtoMessageBodyWriter implements MessageBodyWriter<MyDto> { |
| 60 | + javax.ws.rs.core.Response response = builder.get(); |
235 | 61 |
|
236 |
| - @Override |
237 |
| - public boolean isWriteable( |
238 |
| - Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { |
239 |
| - return true; |
240 |
| - } |
| 62 | + String responseBody = response.readEntity(String.class); |
241 | 63 |
|
242 |
| - @Override |
243 |
| - public void writeTo( |
244 |
| - MyDto myDto, |
245 |
| - Class<?> type, |
246 |
| - Type genericType, |
247 |
| - Annotation[] annotations, |
248 |
| - MediaType mediaType, |
249 |
| - MultivaluedMap<String, Object> httpHeaders, |
250 |
| - OutputStream entityStream) |
251 |
| - throws IOException, WebApplicationException { |
252 |
| - entityStream.write((myDto.getJson()).getBytes()); |
253 |
| - } |
| 64 | + return new Response( |
| 65 | + responseBody == null || responseBody.isEmpty() ? null : responseBody, response.getStatus()); |
254 | 66 | }
|
255 | 67 | }
|
0 commit comments