Skip to content

Commit c075409

Browse files
authored
added support to jakartaee for jaxrs (elastic#2248)
* added support to jakartaee for jaxrs * added test for jakartaee * local save - should solve problem with common JerseyTest(conflicts in jakartaee-test classes * refactored jaxrs tests * added miss headers. added entry to changelog * added license headers after tests.
1 parent e2c6207 commit c075409

File tree

12 files changed

+804
-201
lines changed

12 files changed

+804
-201
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ by the agent may be different. This was done in order to improve the integration
4949
This replaces the now deprecated `span_frames_min_duration` option.
5050
The difference is that the new option has more intuitive semantics for negative values (never collect stack trace) and zero (always collect stack trace). - {pull}2220[#2220]
5151
* Add support to Jakarta EE for JAX-WS - {pull}2247[#2247]
52+
* Add support to Jakarta EE for JAX-RS - {pull}2248[#2248]
5253
5354
[float]
5455
===== Performance improvements
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>apm-agent-plugins</artifactId>
7+
<groupId>co.elastic.apm</groupId>
8+
<version>1.26.1-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>apm-jaxrs-plugin-jakartaee-test</artifactId>
13+
<name>${project.groupId}:${project.artifactId}</name>
14+
15+
<properties>
16+
<apm-agent-parent.base.dir>${project.basedir}/../..</apm-agent-parent.base.dir>
17+
<version.jersey>3.0.3</version.jersey>
18+
</properties>
19+
20+
<dependencies>
21+
<dependency>
22+
<groupId>jakarta.ws.rs</groupId>
23+
<artifactId>jakarta.ws.rs-api</artifactId>
24+
<version>3.0.0</version>
25+
<scope>test</scope>
26+
</dependency>
27+
<dependency>
28+
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
29+
<artifactId>jersey-test-framework-provider-inmemory</artifactId>
30+
<version>${version.jersey}</version>
31+
<scope>test</scope>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.glassfish.jersey.inject</groupId>
35+
<artifactId>jersey-hk2</artifactId>
36+
<version>${version.jersey}</version>
37+
<scope>test</scope>
38+
</dependency>
39+
<dependency>
40+
<groupId>javax.xml.bind</groupId>
41+
<artifactId>jaxb-api</artifactId>
42+
<version>2.3.0</version>
43+
<scope>test</scope>
44+
</dependency>
45+
<dependency>
46+
<groupId>javax.activation</groupId>
47+
<artifactId>activation</artifactId>
48+
<version>1.1.1</version>
49+
<scope>test</scope>
50+
</dependency>
51+
<dependency>
52+
<groupId>${project.groupId}</groupId>
53+
<artifactId>apm-jaxrs-plugin</artifactId>
54+
<version>${project.version}</version>
55+
<scope>test</scope>
56+
</dependency>
57+
<dependency>
58+
<groupId>${project.groupId}</groupId>
59+
<artifactId>apm-jaxrs-plugin</artifactId>
60+
<version>${project.version}</version>
61+
<type>test-jar</type>
62+
<scope>test</scope>
63+
</dependency>
64+
</dependencies>
65+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package co.elastic.apm.agent.jaxrs;
20+
21+
import co.elastic.apm.agent.MockReporter;
22+
import co.elastic.apm.agent.MockTracer;
23+
import co.elastic.apm.agent.bci.ElasticApmAgent;
24+
import co.elastic.apm.agent.impl.ElasticApmTracer;
25+
import co.elastic.apm.agent.impl.transaction.Transaction;
26+
import co.elastic.apm.agent.objectpool.TestObjectPoolFactory;
27+
import jakarta.ws.rs.GET;
28+
import jakarta.ws.rs.POST;
29+
import jakarta.ws.rs.Path;
30+
import jakarta.ws.rs.PathParam;
31+
import jakarta.ws.rs.core.Application;
32+
import org.glassfish.jersey.server.ResourceConfig;
33+
import org.glassfish.jersey.test.JerseyTest;
34+
import org.junit.After;
35+
import org.junit.Before;
36+
import org.junit.Test;
37+
import org.stagemonitor.configuration.ConfigurationRegistry;
38+
39+
import java.io.IOException;
40+
41+
import static org.assertj.core.api.Assertions.assertThat;
42+
43+
/**
44+
* Test jax-rs instrumentation
45+
*/
46+
public class JakartaeeJaxRsTransactionNameInstrumentationTest extends JerseyTest {
47+
48+
private ElasticApmTracer tracer;
49+
private MockReporter reporter;
50+
private ConfigurationRegistry config;
51+
private TestObjectPoolFactory objectPoolFactory;
52+
53+
private JaxRsTransactionNameInstrumentationTestHelper helper;
54+
55+
@Before
56+
public void before() {
57+
MockTracer.MockInstrumentationSetup mockInstrumentationSetup = MockTracer.createMockInstrumentationSetup();
58+
reporter = mockInstrumentationSetup.getReporter();
59+
config = mockInstrumentationSetup.getConfig();
60+
tracer = mockInstrumentationSetup.getTracer();
61+
objectPoolFactory = mockInstrumentationSetup.getObjectPoolFactory();
62+
helper = new JaxRsTransactionNameInstrumentationTestHelper(tracer, reporter, config, objectPoolFactory, this::doRequest);
63+
}
64+
65+
@After
66+
public void after() {
67+
try {
68+
reporter.assertRecycledAfterDecrementingReferences();
69+
objectPoolFactory.checkAllPooledObjectsHaveBeenRecycled();
70+
} finally {
71+
reporter.reset();
72+
objectPoolFactory.reset();
73+
ElasticApmAgent.reset();
74+
}
75+
}
76+
77+
@Test
78+
public void testJaxRsTransactionNameWithoutJaxrsAnnotationInheritance() {
79+
helper.testJaxRsTransactionNameWithoutJaxrsAnnotationInheritance();
80+
}
81+
82+
@Test
83+
public void testJaxRsTransactionNameWithJaxrsAnnotationInheritance() {
84+
helper.testJaxRsTransactionNameWithJaxrsAnnotationInheritance();
85+
}
86+
87+
@Test
88+
public void testJaxRsTransactionNameMethodDelegation() {
89+
helper.testJaxRsTransactionNameMethodDelegation();
90+
}
91+
92+
@Test
93+
public void testProxyClassInstrumentationExclusion() {
94+
helper.testProxyClassInstrumentationExclusion();
95+
}
96+
97+
@Test
98+
public void testJaxRsTransactionNameNonSampledTransactions() throws IOException {
99+
helper.testJaxRsTransactionNameNonSampledTransactions();
100+
}
101+
102+
@Test
103+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceEnabled() {
104+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceEnabled();
105+
}
106+
107+
@Test
108+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceDisabled() {
109+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceDisabled();
110+
}
111+
112+
@Test
113+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnMethodWithPathAnnotation() {
114+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnMethodWithPathAnnotation();
115+
}
116+
117+
@Test
118+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnMethodWithPathAnnotationWithSlash() {
119+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnMethodWithPathAnnotationWithSlash();
120+
}
121+
122+
@Test
123+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnMethodWithComplexPath() {
124+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnMethodWithComplexPath();
125+
}
126+
127+
@Test
128+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnEmptyPathResource() {
129+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnEmptyPathResource();
130+
}
131+
132+
@Test
133+
public void testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnResourceWithPathAndPathOnInterface() {
134+
helper.testJaxRsTransactionNameFromPathAnnotationInheritanceEnabledOnResourceWithPathAndPathOnInterface();
135+
}
136+
137+
@Test
138+
public void testJaxRsFrameworkNameAndVersion() throws IOException {
139+
helper.testJaxRsFrameworkNameAndVersion("3.0.0");
140+
}
141+
142+
@Test
143+
public void testJaxRsFrameworkNameAndVersionWithNonSampledTransaction() throws IOException {
144+
helper.testJaxRsFrameworkNameAndVersionWithNonSampledTransaction("3.0.0");
145+
}
146+
147+
/**
148+
* Make a GET request against the target path wrapped in an apm transaction.
149+
*
150+
* @param path the path to make the get request against
151+
*/
152+
private void doRequest(String path) {
153+
final Transaction request = tracer.startRootTransaction(null)
154+
.withType("request")
155+
.activate();
156+
try {
157+
assertThat(getClient().target(getBaseUri()).path(path).request().buildGet().invoke(String.class)).isEqualTo("ok");
158+
} finally {
159+
request
160+
.deactivate()
161+
.end();
162+
}
163+
}
164+
/**
165+
* @return configuration for the jersey test server. Includes all resource classes in the co.elastic.apm.agent.jaxrs.resources package.
166+
*/
167+
@Override
168+
protected Application configure() {
169+
return new ResourceConfig(
170+
ResourceWithPath.class,
171+
ResourceWithPathOnInterface.class,
172+
ResourceWithPathOnAbstract.class,
173+
ProxiedClass$$$view.class,
174+
ProxiedClass$Proxy.class,
175+
ResourceWithPathOnMethod.class,
176+
ResourceWithPathOnMethodSlash.class,
177+
MethodDelegationResource.class,
178+
FooBarResource.class,
179+
EmptyPathResource.class,
180+
ResourceWithPathAndWithPathOnInterface.class);
181+
}
182+
183+
public interface SuperResourceInterface {
184+
@GET
185+
String testMethod();
186+
}
187+
188+
@Path("testInterface")
189+
public interface ResourceInterfaceWithPath extends SuperResourceInterface {
190+
String testMethod();
191+
}
192+
193+
public interface ResourceInterfaceWithoutPath extends SuperResourceInterface {
194+
String testMethod();
195+
}
196+
197+
public abstract static class AbstractResourceClassWithoutPath implements ResourceInterfaceWithoutPath {
198+
}
199+
200+
@Path("testAbstract")
201+
public abstract static class AbstractResourceClassWithPath implements ResourceInterfaceWithoutPath {
202+
}
203+
204+
@Path("testViewProxy")
205+
public static class ProxiedClass$$$view implements SuperResourceInterface {
206+
public String testMethod() {
207+
return "ok";
208+
}
209+
}
210+
211+
@Path("testProxyProxy")
212+
public static class ProxiedClass$Proxy implements SuperResourceInterface {
213+
public String testMethod() {
214+
return "ok";
215+
}
216+
}
217+
218+
@Path("test")
219+
public static class ResourceWithPath extends AbstractResourceClassWithoutPath {
220+
public String testMethod() {
221+
return "ok";
222+
}
223+
}
224+
225+
@Path("methodDelegation")
226+
public static class MethodDelegationResource {
227+
@GET
228+
@Path("methodA")
229+
public String methodA() {
230+
methodB();
231+
return "ok";
232+
}
233+
234+
@POST
235+
public void methodB() {
236+
}
237+
}
238+
239+
@Path("/foo/")
240+
public static class FooResource {
241+
@GET
242+
@Path("/ignore")
243+
public String testMethod() {
244+
return "ok";
245+
}
246+
}
247+
248+
public static class FooBarResource extends FooResource {
249+
@GET
250+
@Path("/bar")
251+
@Override
252+
public String testMethod() {
253+
return "ok";
254+
}
255+
}
256+
257+
@Path("testWithPathMethod")
258+
public static class ResourceWithPathOnMethod extends AbstractResourceClassWithoutPath {
259+
260+
@Override
261+
public String testMethod() {
262+
return "ok";
263+
}
264+
265+
@GET
266+
@Path("{id}/")
267+
public String testMethodById(@PathParam("id") String id) {
268+
return "ok";
269+
}
270+
}
271+
272+
@Path("testWithPathMethodSlash")
273+
public static class ResourceWithPathOnMethodSlash extends AbstractResourceClassWithoutPath {
274+
275+
@Override
276+
public String testMethod() {
277+
return "ok";
278+
}
279+
280+
@GET
281+
@Path("/{id}")
282+
public String testMethodById(@PathParam("id") String id) {
283+
return "ok";
284+
}
285+
}
286+
287+
@Path("")
288+
public static class EmptyPathResource {
289+
@GET
290+
public String testMethod() {
291+
return "ok";
292+
}
293+
}
294+
295+
public static class ResourceWithPathAndWithPathOnInterface implements ResourceInterfaceWithPath {
296+
@Override
297+
@GET
298+
@Path("test")
299+
public String testMethod() {
300+
return "ok";
301+
}
302+
}
303+
304+
public static class ResourceWithPathOnAbstract extends AbstractResourceClassWithPath {
305+
public String testMethod() {
306+
return "ok";
307+
}
308+
}
309+
310+
public static class ResourceWithPathOnInterface implements ResourceInterfaceWithPath {
311+
public String testMethod() {
312+
return "ok";
313+
}
314+
}
315+
}

0 commit comments

Comments
 (0)