JAX-RS ApplicationPath annotation (#2824)
This commit is contained in:
parent
c4071c1c94
commit
a3c0b44b31
|
|
@ -0,0 +1,22 @@
|
||||||
|
ext {
|
||||||
|
skipPublish = true
|
||||||
|
}
|
||||||
|
apply from: "$rootDir/gradle/java.gradle"
|
||||||
|
|
||||||
|
// add repo for org.gradle:gradle-tooling-api which org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain depends on
|
||||||
|
repositories {
|
||||||
|
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly "javax:javaee-api:7.0"
|
||||||
|
|
||||||
|
api project(':testing-common')
|
||||||
|
implementation deps.opentelemetryApi
|
||||||
|
|
||||||
|
def arquillianVersion = '1.4.0.Final'
|
||||||
|
implementation "org.jboss.arquillian.junit:arquillian-junit-container:${arquillianVersion}"
|
||||||
|
implementation "org.jboss.arquillian.protocol:arquillian-protocol-servlet:${arquillianVersion}"
|
||||||
|
implementation 'org.jboss.arquillian.spock:arquillian-spock-container:1.0.0.CR1'
|
||||||
|
api "org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain:3.1.3"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static io.opentelemetry.api.trace.SpanKind.SERVER
|
||||||
|
|
||||||
|
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||||
|
import io.opentelemetry.instrumentation.test.utils.OkHttpUtils
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.jboss.arquillian.container.test.api.Deployment
|
||||||
|
import org.jboss.arquillian.container.test.api.RunAsClient
|
||||||
|
import org.jboss.arquillian.spock.ArquillianSputnik
|
||||||
|
import org.jboss.arquillian.test.api.ArquillianResource
|
||||||
|
import org.jboss.shrinkwrap.api.ShrinkWrap
|
||||||
|
import org.jboss.shrinkwrap.api.asset.EmptyAsset
|
||||||
|
import org.jboss.shrinkwrap.api.spec.WebArchive
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import spock.lang.Unroll
|
||||||
|
import test.CdiRestResource
|
||||||
|
import test.EjbRestResource
|
||||||
|
import test.RestApplication
|
||||||
|
|
||||||
|
@RunWith(ArquillianSputnik)
|
||||||
|
@RunAsClient
|
||||||
|
abstract class ArquillianRestTest extends AgentInstrumentationSpecification {
|
||||||
|
|
||||||
|
static OkHttpClient client = OkHttpUtils.client()
|
||||||
|
|
||||||
|
@ArquillianResource
|
||||||
|
static URI url
|
||||||
|
|
||||||
|
@Deployment
|
||||||
|
static WebArchive createDeployment() {
|
||||||
|
return ShrinkWrap.create(WebArchive)
|
||||||
|
.addClass(RestApplication)
|
||||||
|
.addClass(CdiRestResource)
|
||||||
|
.addClass(EjbRestResource)
|
||||||
|
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
|
||||||
|
}
|
||||||
|
|
||||||
|
def getContextRoot() {
|
||||||
|
return url.getPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "test #path"() {
|
||||||
|
when:
|
||||||
|
Request request = new Request.Builder().url(HttpUrl.get(url.resolve(path))).build()
|
||||||
|
Response response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
then:
|
||||||
|
response.withCloseable {
|
||||||
|
assert response.code() == 200
|
||||||
|
assert response.body().string() == "hello"
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
and:
|
||||||
|
assertTraces(1) {
|
||||||
|
trace(0, 2) {
|
||||||
|
span(0) {
|
||||||
|
name getContextRoot() + path
|
||||||
|
kind SERVER
|
||||||
|
hasNoParent()
|
||||||
|
}
|
||||||
|
span(1) {
|
||||||
|
name className + ".hello"
|
||||||
|
childOf span(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
where:
|
||||||
|
path | className
|
||||||
|
"rest-app/cdiHello" | "CdiRestResource"
|
||||||
|
"rest-app/ejbHello" | "EjbRestResource"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ import java.util.Set;
|
||||||
import javax.ws.rs.ApplicationPath;
|
import javax.ws.rs.ApplicationPath;
|
||||||
import javax.ws.rs.core.Application;
|
import javax.ws.rs.core.Application;
|
||||||
|
|
||||||
@ApplicationPath("/")
|
@ApplicationPath("/rest-app/")
|
||||||
public class RestApplication extends Application {
|
public class RestApplication extends Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<arquillian xmlns="http://jboss.org/schema/arquillian"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://jboss.org/schema/arquillian
|
||||||
|
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
|
||||||
|
|
||||||
|
<defaultProtocol type="Servlet 3.0" />
|
||||||
|
|
||||||
|
<container qualifier="wildfly-embedded" default="true">
|
||||||
|
<configuration>
|
||||||
|
<property name="jbossHome">build/server/wildfly-18.0.0.Final</property>
|
||||||
|
<property name="modulePath">build/server/wildfly-18.0.0.Final/modules</property>
|
||||||
|
</configuration>
|
||||||
|
</container>
|
||||||
|
</arquillian>
|
||||||
|
|
@ -14,6 +14,7 @@ import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
import io.opentelemetry.instrumentation.api.tracer.ServerSpan;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ClassHierarchyIterable;
|
import io.opentelemetry.javaagent.instrumentation.api.ClassHierarchyIterable;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.jaxrs.JaxrsContextPath;
|
||||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
@ -66,6 +67,7 @@ public class JaxRsAnnotationsTracer extends BaseTracer {
|
||||||
// empty when method and class don't have a jax-rs path annotation, this can happen when
|
// empty when method and class don't have a jax-rs path annotation, this can happen when
|
||||||
// creating an "abort" span, see RequestContextHelper.
|
// creating an "abort" span, see RequestContextHelper.
|
||||||
if (!pathBasedSpanName.isEmpty()) {
|
if (!pathBasedSpanName.isEmpty()) {
|
||||||
|
pathBasedSpanName = JaxrsContextPath.prepend(context, pathBasedSpanName);
|
||||||
pathBasedSpanName = ServletContextPath.prepend(context, pathBasedSpanName);
|
pathBasedSpanName = ServletContextPath.prepend(context, pathBasedSpanName);
|
||||||
}
|
}
|
||||||
if (serverSpan == null) {
|
if (serverSpan == null) {
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,20 @@ muzzle {
|
||||||
group = "org.apache.cxf"
|
group = "org.apache.cxf"
|
||||||
module = "cxf-rt-frontend-jaxrs"
|
module = "cxf-rt-frontend-jaxrs"
|
||||||
versions = "[3.2,)"
|
versions = "[3.2,)"
|
||||||
|
extraDependency "javax.servlet:javax.servlet-api:3.1.0"
|
||||||
|
}
|
||||||
|
pass {
|
||||||
|
group = "org.apache.tomee"
|
||||||
|
module = "openejb-cxf-rs"
|
||||||
|
// earlier versions of tomee use cxf older than 3.2
|
||||||
|
versions = "(8,)"
|
||||||
|
extraDependency "javax.servlet:javax.servlet-api:3.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||||
|
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
|
||||||
library group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxrs', version: '3.2.0'
|
library group: 'org.apache.cxf', name: 'cxf-rt-frontend-jaxrs', version: '3.2.0'
|
||||||
|
|
||||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||||
|
|
@ -21,6 +30,7 @@ dependencies {
|
||||||
|
|
||||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||||
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
||||||
|
testImplementation group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '9.4.6.v20170531'
|
||||||
|
|
||||||
testLibrary group: 'org.apache.cxf', name: 'cxf-rt-transports-http-jetty', version: '3.2.0'
|
testLibrary group: 'org.apache.cxf', name: 'cxf-rt-transports-http-jetty', version: '3.2.0'
|
||||||
testLibrary group: 'org.apache.cxf', name: 'cxf-rt-ws-policy', version: '3.2.0'
|
testLibrary group: 'org.apache.cxf', name: 'cxf-rt-ws-policy', version: '3.2.0'
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@AutoService(InstrumentationModule.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
|
|
@ -19,6 +20,9 @@ public class CxfInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TypeInstrumentation> typeInstrumentations() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return Collections.singletonList(new CxfRequestContextInstrumentation());
|
return asList(
|
||||||
|
new CxfRequestContextInstrumentation(),
|
||||||
|
new CxfServletControllerInstrumentation(),
|
||||||
|
new CxfRsHttpListenerInstrumentation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.jaxrs.JaxrsContextPath;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
|
// TomEE specific instrumentation
|
||||||
|
public class CxfRsHttpListenerInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.apache.openejb.server.cxf.rs.CxfRsHttpListener");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod().and(named("doInvoke")),
|
||||||
|
CxfRsHttpListenerInstrumentation.class.getName() + "$InvokeAdvice");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvokeAdvice {
|
||||||
|
|
||||||
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
|
public static void onEnter(
|
||||||
|
@Advice.FieldValue("pattern") String pattern, @Advice.Local("otelScope") Scope scope) {
|
||||||
|
Context context = JaxrsContextPath.init(Java8BytecodeBridge.currentContext(), pattern);
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
public static void stopSpan(@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope != null) {
|
||||||
|
scope.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.jaxrs.JaxrsContextPath;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
|
public class CxfServletControllerInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.apache.cxf.transport.servlet.ServletController");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return Collections.singletonMap(
|
||||||
|
isMethod()
|
||||||
|
.and(isPublic())
|
||||||
|
.and(named("invokeDestination"))
|
||||||
|
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest"))),
|
||||||
|
CxfServletControllerInstrumentation.class.getName() + "$InvokeAdvice");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvokeAdvice {
|
||||||
|
|
||||||
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
|
public static void onEnter(
|
||||||
|
@Advice.Argument(0) HttpServletRequest httpServletRequest,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
Context context =
|
||||||
|
JaxrsContextPath.init(
|
||||||
|
Java8BytecodeBridge.currentContext(), httpServletRequest.getServletPath());
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
public static void stopSpan(@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope != null) {
|
||||||
|
scope.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import javax.ws.rs.core.Response
|
||||||
import javax.ws.rs.ext.ExceptionMapper
|
import javax.ws.rs.ext.ExceptionMapper
|
||||||
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean
|
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean
|
||||||
import org.apache.cxf.endpoint.Server
|
import org.apache.cxf.endpoint.Server
|
||||||
|
import test.JaxRsTestApplication
|
||||||
|
|
||||||
class CxfHttpServerTest extends JaxRsHttpServerTest<Server> {
|
class CxfHttpServerTest extends JaxRsHttpServerTest<Server> {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CxfJettyHttpServerTest extends JaxRsJettyHttpServerTest {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app version="3.0" metadata-complete="false"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>CXFNonSpringJaxrsServlet</servlet-name>
|
||||||
|
<servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>javax.ws.rs.Application</param-name>
|
||||||
|
<param-value>test.JaxRsApplicationPathTestApplication</param-value>
|
||||||
|
</init-param>
|
||||||
|
<async-supported>true</async-supported>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>CXFNonSpringJaxrsServlet</servlet-name>
|
||||||
|
<url-pattern>/rest-app/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
</web-app>
|
||||||
|
|
@ -7,12 +7,21 @@ muzzle {
|
||||||
group = "org.glassfish.jersey.core"
|
group = "org.glassfish.jersey.core"
|
||||||
module = "jersey-server"
|
module = "jersey-server"
|
||||||
versions = "[2.0,3.0.0)"
|
versions = "[2.0,3.0.0)"
|
||||||
|
extraDependency "javax.servlet:javax.servlet-api:3.1.0"
|
||||||
|
}
|
||||||
|
pass {
|
||||||
|
group = "org.glassfish.jersey.containers"
|
||||||
|
module = "jersey-container-servlet"
|
||||||
|
versions = "[2.0,3.0.0)"
|
||||||
|
extraDependency "javax.servlet:javax.servlet-api:3.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||||
compileOnly group: 'org.glassfish.jersey.core', name: 'jersey-server', version: '2.0'
|
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
|
||||||
|
library group: 'org.glassfish.jersey.core', name: 'jersey-server', version: '2.0'
|
||||||
|
library group: 'org.glassfish.jersey.containers', name: 'jersey-container-servlet', version: '2.0'
|
||||||
|
|
||||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||||
|
|
||||||
|
|
@ -20,6 +29,7 @@ dependencies {
|
||||||
testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent')
|
testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent')
|
||||||
|
|
||||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||||
|
testImplementation group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '8.0.0.v20110901'
|
||||||
|
|
||||||
// First version with DropwizardTestSupport:
|
// First version with DropwizardTestSupport:
|
||||||
testLibrary group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.8.0'
|
testLibrary group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.8.0'
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@AutoService(InstrumentationModule.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
|
|
@ -19,6 +20,7 @@ public class JerseyInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TypeInstrumentation> typeInstrumentations() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return Collections.singletonList(new JerseyRequestContextInstrumentation());
|
return asList(
|
||||||
|
new JerseyRequestContextInstrumentation(), new JerseyServletContainerInstrumentation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonMap;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.jaxrs.JaxrsContextPath;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
|
public class JerseyServletContainerInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.glassfish.jersey.servlet.ServletContainer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return singletonMap(
|
||||||
|
isMethod()
|
||||||
|
.and(named("service"))
|
||||||
|
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||||
|
.and(takesArgument(1, named("javax.servlet.http.HttpServletResponse"))),
|
||||||
|
JerseyServletContainerInstrumentation.class.getName() + "$ServiceAdvice");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ServiceAdvice {
|
||||||
|
|
||||||
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
|
public static void onEnter(
|
||||||
|
@Advice.Argument(0) HttpServletRequest httpServletRequest,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
Context context =
|
||||||
|
JaxrsContextPath.init(
|
||||||
|
Java8BytecodeBridge.currentContext(), httpServletRequest.getServletPath());
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
public static void stopSpan(@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope != null) {
|
||||||
|
scope.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import org.eclipse.jetty.server.Server
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||||
import org.glassfish.jersey.server.ResourceConfig
|
import org.glassfish.jersey.server.ResourceConfig
|
||||||
import org.glassfish.jersey.servlet.ServletContainer
|
import org.glassfish.jersey.servlet.ServletContainer
|
||||||
|
import test.JaxRsTestApplication
|
||||||
|
|
||||||
class JerseyHttpServerTest extends JaxRsHttpServerTest<Server> {
|
class JerseyHttpServerTest extends JaxRsHttpServerTest<Server> {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class JerseyJettyHttpServerTest extends JaxRsJettyHttpServerTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean asyncCancelHasSendError() {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.servlet.ServletContextEvent
|
||||||
|
import javax.servlet.ServletContextListener
|
||||||
|
import org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer
|
||||||
|
import test.JaxRsApplicationPathTestApplication
|
||||||
|
|
||||||
|
// ServletContainerInitializer isn't automatically called due to the way this test is set up
|
||||||
|
// so we call it ourself
|
||||||
|
class JerseyStartupListener implements ServletContextListener {
|
||||||
|
@Override
|
||||||
|
void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
|
new JerseyServletContainerInitializer().onStartup(Collections.singleton(JaxRsApplicationPathTestApplication),
|
||||||
|
servletContextEvent.getServletContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app version="3.0" metadata-complete="false"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
|
|
||||||
|
<listener>
|
||||||
|
<listener-class>JerseyStartupListener</listener-class>
|
||||||
|
</listener>
|
||||||
|
</web-app>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
ext {
|
||||||
|
skipPublish = true
|
||||||
|
}
|
||||||
|
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||||
|
|
||||||
|
// add repo for org.gradle:gradle-tooling-api which org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain
|
||||||
|
// which is used by jaxrs-2.0-arquillian-testing depends on
|
||||||
|
repositories {
|
||||||
|
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-arquillian-testing')
|
||||||
|
testImplementation "fish.payara.arquillian:arquillian-payara-server-embedded:2.4.1"
|
||||||
|
testImplementation 'fish.payara.extras:payara-embedded-web:5.2021.2'
|
||||||
|
|
||||||
|
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||||
|
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||||
|
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0:javaagent')
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PayaraRestTest extends ArquillianRestTest {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
<arquillian xmlns="http://jboss.org/schema/arquillian"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://jboss.org/schema/arquillian
|
||||||
|
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
|
||||||
|
|
||||||
|
<defaultProtocol type="Servlet 3.0" />
|
||||||
|
|
||||||
|
<container qualifier="payara-embedded" default="true">
|
||||||
|
<configuration>
|
||||||
|
<!-- by default runs on port 8181 -->
|
||||||
|
</configuration>
|
||||||
|
</container>
|
||||||
|
</arquillian>
|
||||||
|
|
@ -30,11 +30,13 @@ dependencies {
|
||||||
testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent')
|
testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent')
|
||||||
|
|
||||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||||
|
testImplementation group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '8.0.0.v20110901'
|
||||||
|
|
||||||
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.0.4.Final') {
|
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.0.4.Final') {
|
||||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||||
}
|
}
|
||||||
testLibrary group: 'io.undertow', name: 'undertow-servlet', version: '1.0.0.Final'
|
testLibrary group: 'io.undertow', name: 'undertow-servlet', version: '1.0.0.Final'
|
||||||
|
testLibrary group: 'org.jboss.resteasy', name: 'resteasy-servlet-initializer', version: '3.0.4.Final'
|
||||||
|
|
||||||
latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.+'
|
latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.+'
|
||||||
latestDepTestLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.+') {
|
latestDepTestLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.+') {
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@AutoService(InstrumentationModule.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
|
|
@ -19,6 +20,8 @@ public class Resteasy30InstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TypeInstrumentation> typeInstrumentations() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return Collections.singletonList(new Resteasy30RequestContextInstrumentation());
|
return asList(
|
||||||
|
new Resteasy30RequestContextInstrumentation(),
|
||||||
|
new Resteasy30ServletContainerDispatcherInstrumentation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.jaxrs.JaxrsContextPath;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
|
public class Resteasy30ServletContainerDispatcherInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return Collections.singletonMap(
|
||||||
|
isMethod().and(named("service")),
|
||||||
|
Resteasy30ServletContainerDispatcherInstrumentation.class.getName() + "$ServiceAdvice");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ServiceAdvice {
|
||||||
|
|
||||||
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
|
public static void onEnter(
|
||||||
|
@Advice.FieldValue("servletMappingPrefix") String servletMappingPrefix,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
Context context =
|
||||||
|
JaxrsContextPath.init(Java8BytecodeBridge.currentContext(), servletMappingPrefix);
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
public static void stopSpan(@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope != null) {
|
||||||
|
scope.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import io.undertow.Undertow
|
import io.undertow.Undertow
|
||||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
||||||
|
import test.JaxRsTestApplication
|
||||||
|
|
||||||
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ResteasyJettyHttpServerTest extends JaxRsJettyHttpServerTest {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.servlet.ServletContextEvent
|
||||||
|
import javax.servlet.ServletContextListener
|
||||||
|
import org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer
|
||||||
|
import test.JaxRsApplicationPathTestApplication
|
||||||
|
|
||||||
|
// ServletContainerInitializer isn't automatically called due to the way this test is set up
|
||||||
|
// so we call it ourself
|
||||||
|
class ResteasyStartupListener implements ServletContextListener {
|
||||||
|
@Override
|
||||||
|
void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
|
new ResteasyServletInitializer().onStartup(Collections.singleton(JaxRsApplicationPathTestApplication),
|
||||||
|
servletContextEvent.getServletContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app version="3.0" metadata-complete="false"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
|
|
||||||
|
<listener>
|
||||||
|
<listener-class>ResteasyStartupListener</listener-class>
|
||||||
|
</listener>
|
||||||
|
</web-app>
|
||||||
|
|
@ -30,10 +30,12 @@ dependencies {
|
||||||
testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent')
|
testInstrumentation project(':instrumentation:servlet:servlet-javax-common:javaagent')
|
||||||
|
|
||||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||||
|
testImplementation group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '8.0.0.v20110901'
|
||||||
|
|
||||||
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.1.0.Final') {
|
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.1.0.Final') {
|
||||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||||
}
|
}
|
||||||
|
testLibrary group: 'org.jboss.resteasy', name: 'resteasy-servlet-initializer', version: '3.1.0.Final'
|
||||||
|
|
||||||
// artifact name changed from 'resteasy-jaxrs' to 'resteasy-core' starting from version 4.0.0
|
// artifact name changed from 'resteasy-jaxrs' to 'resteasy-core' starting from version 4.0.0
|
||||||
latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-core', version: '+'
|
latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-core', version: '+'
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@AutoService(InstrumentationModule.class)
|
@AutoService(InstrumentationModule.class)
|
||||||
|
|
@ -19,6 +20,8 @@ public class Resteasy31InstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TypeInstrumentation> typeInstrumentations() {
|
public List<TypeInstrumentation> typeInstrumentations() {
|
||||||
return Collections.singletonList(new Resteasy31RequestContextInstrumentation());
|
return asList(
|
||||||
|
new Resteasy31RequestContextInstrumentation(),
|
||||||
|
new Resteasy31ServletContainerDispatcherInstrumentation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.jaxrs.v2_0;
|
||||||
|
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
|
import io.opentelemetry.javaagent.instrumentation.api.jaxrs.JaxrsContextPath;
|
||||||
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.bytebuddy.asm.Advice;
|
||||||
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
import net.bytebuddy.description.type.TypeDescription;
|
||||||
|
import net.bytebuddy.matcher.ElementMatcher;
|
||||||
|
|
||||||
|
public class Resteasy31ServletContainerDispatcherInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ElementMatcher<TypeDescription> typeMatcher() {
|
||||||
|
return named("org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
|
||||||
|
return Collections.singletonMap(
|
||||||
|
isMethod().and(named("service")),
|
||||||
|
Resteasy31ServletContainerDispatcherInstrumentation.class.getName() + "$ServiceAdvice");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ServiceAdvice {
|
||||||
|
|
||||||
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
|
public static void onEnter(
|
||||||
|
@Advice.FieldValue("servletMappingPrefix") String servletMappingPrefix,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
Context context =
|
||||||
|
JaxrsContextPath.init(Java8BytecodeBridge.currentContext(), servletMappingPrefix);
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
public static void stopSpan(@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope != null) {
|
||||||
|
scope.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
import io.undertow.Undertow
|
import io.undertow.Undertow
|
||||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
||||||
|
import test.JaxRsTestApplication
|
||||||
|
|
||||||
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ResteasyJettyHttpServerTest extends JaxRsJettyHttpServerTest {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.servlet.ServletContextEvent
|
||||||
|
import javax.servlet.ServletContextListener
|
||||||
|
import org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer
|
||||||
|
import test.JaxRsApplicationPathTestApplication
|
||||||
|
|
||||||
|
// ServletContainerInitializer isn't automatically called due to the way this test is set up
|
||||||
|
// so we call it ourself
|
||||||
|
class ResteasyStartupListener implements ServletContextListener {
|
||||||
|
@Override
|
||||||
|
void contextInitialized(ServletContextEvent servletContextEvent) {
|
||||||
|
new ResteasyServletInitializer().onStartup(Collections.singleton(JaxRsApplicationPathTestApplication),
|
||||||
|
servletContextEvent.getServletContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void contextDestroyed(ServletContextEvent servletContextEvent) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app version="3.0" metadata-complete="false"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
|
|
||||||
|
<listener>
|
||||||
|
<listener-class>ResteasyStartupListener</listener-class>
|
||||||
|
</listener>
|
||||||
|
</web-app>
|
||||||
|
|
@ -13,4 +13,6 @@ dependencies {
|
||||||
implementation project(':javaagent-api')
|
implementation project(':javaagent-api')
|
||||||
implementation project(':instrumentation-api')
|
implementation project(':instrumentation-api')
|
||||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||||
|
|
||||||
|
compileOnly group: 'org.eclipse.jetty', name: 'jetty-webapp', version: '8.0.0.v20110901'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import okhttp3.HttpUrl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import spock.lang.Unroll
|
import spock.lang.Unroll
|
||||||
|
import test.JaxRsTestResource
|
||||||
|
|
||||||
abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements AgentTestTrait {
|
abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements AgentTestTrait {
|
||||||
@Unroll
|
@Unroll
|
||||||
|
|
@ -225,7 +226,7 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements Agent
|
||||||
}
|
}
|
||||||
childOf((SpanData) parent)
|
childOf((SpanData) parent)
|
||||||
attributes {
|
attributes {
|
||||||
"${SemanticAttributes.CODE_NAMESPACE.key}" "JaxRsTestResource"
|
"${SemanticAttributes.CODE_NAMESPACE.key}" "test.JaxRsTestResource"
|
||||||
"${SemanticAttributes.CODE_FUNCTION.key}" methodName
|
"${SemanticAttributes.CODE_FUNCTION.key}" methodName
|
||||||
if (isCancelled) {
|
if (isCancelled) {
|
||||||
"jaxrs.canceled" true
|
"jaxrs.canceled" true
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static org.eclipse.jetty.util.resource.Resource.newResource
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Server
|
||||||
|
import org.eclipse.jetty.webapp.WebAppContext
|
||||||
|
|
||||||
|
class JaxRsJettyHttpServerTest extends JaxRsHttpServerTest<Server> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Server startServer(int port) {
|
||||||
|
WebAppContext webAppContext = new WebAppContext()
|
||||||
|
webAppContext.setContextPath("/")
|
||||||
|
// set up test application
|
||||||
|
webAppContext.setBaseResource(newResource("src/test/webapp"))
|
||||||
|
|
||||||
|
def jettyServer = new Server(port)
|
||||||
|
jettyServer.connectors.each {
|
||||||
|
it.setHost('localhost')
|
||||||
|
}
|
||||||
|
|
||||||
|
jettyServer.setHandler(webAppContext)
|
||||||
|
jettyServer.start()
|
||||||
|
|
||||||
|
return jettyServer
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void stopServer(Server server) {
|
||||||
|
server.stop()
|
||||||
|
server.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getContextPath() {
|
||||||
|
"/rest-app"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.ERROR
|
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.ERROR
|
||||||
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
|
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.EXCEPTION
|
||||||
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM
|
import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM
|
||||||
|
|
@ -15,6 +17,7 @@ import io.opentelemetry.instrumentation.test.base.HttpServerTest
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.CompletionStage
|
import java.util.concurrent.CompletionStage
|
||||||
import java.util.concurrent.CyclicBarrier
|
import java.util.concurrent.CyclicBarrier
|
||||||
|
import javax.ws.rs.ApplicationPath
|
||||||
import javax.ws.rs.GET
|
import javax.ws.rs.GET
|
||||||
import javax.ws.rs.Path
|
import javax.ws.rs.Path
|
||||||
import javax.ws.rs.PathParam
|
import javax.ws.rs.PathParam
|
||||||
|
|
@ -148,4 +151,8 @@ class JaxRsTestApplication extends Application {
|
||||||
classes.add(JaxRsTestExceptionMapper)
|
classes.add(JaxRsTestExceptionMapper)
|
||||||
return classes
|
return classes
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApplicationPath("/rest-app")
|
||||||
|
class JaxRsApplicationPathTestApplication extends JaxRsTestApplication {
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
ext {
|
||||||
|
skipPublish = true
|
||||||
|
}
|
||||||
|
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||||
|
|
||||||
|
// add repo for org.gradle:gradle-tooling-api which org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain
|
||||||
|
// which is used by jaxrs-2.0-arquillian-testing depends on
|
||||||
|
repositories {
|
||||||
|
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-arquillian-testing')
|
||||||
|
testImplementation "org.apache.tomee:arquillian-tomee-embedded:8.0.6"
|
||||||
|
testImplementation "org.apache.tomee:tomee-embedded:8.0.6"
|
||||||
|
testImplementation "org.apache.tomee:tomee-jaxrs:8.0.6"
|
||||||
|
|
||||||
|
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||||
|
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||||
|
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-cxf-3.2:javaagent')
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javax.enterprise.inject.Vetoed
|
||||||
|
|
||||||
|
// exclude this class from CDI as it causes NullPointerException when tomee is run with jdk8
|
||||||
|
@Vetoed
|
||||||
|
class TomeeRestTest extends ArquillianRestTest {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<arquillian xmlns="http://jboss.org/schema/arquillian"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="
|
||||||
|
http://jboss.org/schema/arquillian
|
||||||
|
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
|
||||||
|
|
||||||
|
<defaultProtocol type="Servlet 3.0" />
|
||||||
|
|
||||||
|
<container qualifier="tomee-embedded" default="true">
|
||||||
|
<configuration>
|
||||||
|
<property name="httpPort">-1</property>
|
||||||
|
<property name="stopPort">-1</property>
|
||||||
|
</configuration>
|
||||||
|
</container>
|
||||||
|
</arquillian>
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
<Pattern>
|
||||||
|
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</Pattern>
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="WARN">
|
||||||
|
<appender-ref ref="console"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<logger name="io.opentelemetry" level="debug"/>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
|
@ -3,6 +3,8 @@ ext {
|
||||||
}
|
}
|
||||||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||||
|
|
||||||
|
// add repo for org.gradle:gradle-tooling-api which org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain
|
||||||
|
// which is used by jaxrs-2.0-arquillian-testing depends on
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
|
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
|
||||||
}
|
}
|
||||||
|
|
@ -14,16 +16,12 @@ configurations {
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation "javax:javaee-api:7.0"
|
testImplementation "javax:javaee-api:7.0"
|
||||||
|
|
||||||
def arquillianVersion = '1.4.0.Final'
|
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-arquillian-testing')
|
||||||
testImplementation "org.jboss.arquillian.junit:arquillian-junit-container:${arquillianVersion}"
|
|
||||||
testImplementation "org.jboss.arquillian.protocol:arquillian-protocol-servlet:${arquillianVersion}"
|
|
||||||
testImplementation "org.wildfly.arquillian:wildfly-arquillian-container-embedded:2.2.0.Final"
|
testImplementation "org.wildfly.arquillian:wildfly-arquillian-container-embedded:2.2.0.Final"
|
||||||
testImplementation 'org.jboss.arquillian.spock:arquillian-spock-container:1.0.0.CR1'
|
|
||||||
testImplementation "org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-gradle-depchain:3.1.3"
|
|
||||||
testImplementation "org.glassfish.jersey.core:jersey-client:2.8"
|
|
||||||
|
|
||||||
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
testInstrumentation project(':instrumentation:servlet:servlet-3.0:javaagent')
|
||||||
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent')
|
||||||
|
testInstrumentation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.0:javaagent')
|
||||||
|
|
||||||
// wildfly version used to run tests
|
// wildfly version used to run tests
|
||||||
testServer "org.wildfly:wildfly-dist:18.0.0.Final@zip"
|
testServer "org.wildfly:wildfly-dist:18.0.0.Final@zip"
|
||||||
|
|
|
||||||
|
|
@ -3,75 +3,5 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import static io.opentelemetry.api.trace.SpanKind.SERVER
|
class WildflyRestTest extends ArquillianRestTest {
|
||||||
|
|
||||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
|
||||||
import javax.ws.rs.client.Client
|
|
||||||
import javax.ws.rs.client.WebTarget
|
|
||||||
import org.glassfish.jersey.client.JerseyClientBuilder
|
|
||||||
import org.jboss.arquillian.container.test.api.Deployment
|
|
||||||
import org.jboss.arquillian.container.test.api.RunAsClient
|
|
||||||
import org.jboss.arquillian.spock.ArquillianSputnik
|
|
||||||
import org.jboss.arquillian.test.api.ArquillianResource
|
|
||||||
import org.jboss.shrinkwrap.api.ShrinkWrap
|
|
||||||
import org.jboss.shrinkwrap.api.asset.EmptyAsset
|
|
||||||
import org.jboss.shrinkwrap.api.spec.WebArchive
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import test.CdiRestResource
|
|
||||||
import test.EjbRestResource
|
|
||||||
import test.RestApplication
|
|
||||||
|
|
||||||
@RunWith(ArquillianSputnik)
|
|
||||||
@RunAsClient
|
|
||||||
class WildflyRestTest extends AgentInstrumentationSpecification {
|
|
||||||
|
|
||||||
@ArquillianResource
|
|
||||||
static URI url
|
|
||||||
|
|
||||||
@Deployment
|
|
||||||
static WebArchive createDeployment() {
|
|
||||||
return ShrinkWrap.create(WebArchive)
|
|
||||||
.addClass(RestApplication)
|
|
||||||
.addClass(CdiRestResource)
|
|
||||||
.addClass(EjbRestResource)
|
|
||||||
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
|
|
||||||
}
|
|
||||||
|
|
||||||
def getContextRoot() {
|
|
||||||
return url.getPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
def "test #path"() {
|
|
||||||
when:
|
|
||||||
Client client = JerseyClientBuilder.newClient()
|
|
||||||
WebTarget webTarget = client.target(url)
|
|
||||||
|
|
||||||
String result = webTarget.path(path)
|
|
||||||
.request()
|
|
||||||
.get()
|
|
||||||
.readEntity(String)
|
|
||||||
|
|
||||||
then:
|
|
||||||
result == "hello"
|
|
||||||
|
|
||||||
and:
|
|
||||||
assertTraces(1) {
|
|
||||||
trace(0, 2) {
|
|
||||||
span(0) {
|
|
||||||
name getContextRoot() + path
|
|
||||||
kind SERVER
|
|
||||||
hasNoParent()
|
|
||||||
}
|
|
||||||
span(1) {
|
|
||||||
name className + ".hello"
|
|
||||||
childOf span(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
where:
|
|
||||||
path | className
|
|
||||||
"cdiHello" | "CdiRestResource"
|
|
||||||
"ejbHello" | "EjbRestResource"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.instrumentation.api.jaxrs;
|
||||||
|
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.ContextKey;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper container for storing context path for jax-rs requests. Jax-rs context path is the path
|
||||||
|
* where jax-rs servlet is mapped or the value of ApplicationPath annotation. Span name is built by
|
||||||
|
* combining servlet context path from {@link
|
||||||
|
* io.opentelemetry.instrumentation.api.servlet.ServletContextPath} jax-rs context path and the Path
|
||||||
|
* annotation from called method or class.
|
||||||
|
*/
|
||||||
|
public final class JaxrsContextPath {
|
||||||
|
private static final ContextKey<String> CONTEXT_KEY =
|
||||||
|
ContextKey.named("opentelemetry-jaxrs-context-path-key");
|
||||||
|
|
||||||
|
private JaxrsContextPath() {}
|
||||||
|
|
||||||
|
public static @Nullable Context init(Context context, String path) {
|
||||||
|
if (path == null || path.isEmpty() || "/".equals(path)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// normalize path to have a leading slash and no trailing slash
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
path = "/" + path;
|
||||||
|
}
|
||||||
|
if (path.endsWith("/")) {
|
||||||
|
path = path.substring(0, path.length() - 1);
|
||||||
|
}
|
||||||
|
return context.with(CONTEXT_KEY, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String prepend(Context context, String spanName) {
|
||||||
|
String value = context.get(CONTEXT_KEY);
|
||||||
|
// checking isEmpty just to avoid unnecessary string concat / allocation
|
||||||
|
if (value != null && !value.isEmpty()) {
|
||||||
|
return value + spanName;
|
||||||
|
} else {
|
||||||
|
return spanName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -190,6 +190,12 @@ public class GlobalIgnoresMatcher extends ElementMatcher.Junction.AbstractBase<T
|
||||||
|| name.contains(".asm.")
|
|| name.contains(".asm.")
|
||||||
|| name.contains("$__sisu")
|
|| name.contains("$__sisu")
|
||||||
|| name.contains("$$EnhancerByProxool$$")
|
|| name.contains("$$EnhancerByProxool$$")
|
||||||
|
// glassfish ejb proxy
|
||||||
|
// We skip instrumenting these because some instrumentations e.g. jax-rs instrument methods
|
||||||
|
// that are annotated with @Path in an interface implemented by the class. We don't really
|
||||||
|
// want to instrument these methods in generated classes as this would create spans that
|
||||||
|
// have the generated class name in them instead of the actual class that handles the call.
|
||||||
|
|| name.contains("__EJB31_Generated__")
|
||||||
|| name.startsWith("org.springframework.core.$Proxy")) {
|
|| name.startsWith("org.springframework.core.$Proxy")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,12 +127,15 @@ include ':instrumentation:http-url-connection:javaagent'
|
||||||
include ':instrumentation:hystrix-1.4:javaagent'
|
include ':instrumentation:hystrix-1.4:javaagent'
|
||||||
include ':instrumentation:java-httpclient:javaagent'
|
include ':instrumentation:java-httpclient:javaagent'
|
||||||
include ':instrumentation:jaxrs:jaxrs-1.0:javaagent'
|
include ':instrumentation:jaxrs:jaxrs-1.0:javaagent'
|
||||||
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-arquillian-testing'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common:javaagent'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-cxf-3.2:javaagent'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-cxf-3.2:javaagent'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0:javaagent'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0:javaagent'
|
||||||
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-payara-testing'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.0:javaagent'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.0:javaagent'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.1:javaagent'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.1:javaagent'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing'
|
||||||
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-tomee-testing'
|
||||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-wildfly-testing'
|
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-wildfly-testing'
|
||||||
include ':instrumentation:jaxrs-client:jaxrs-client-1.1:javaagent'
|
include ':instrumentation:jaxrs-client:jaxrs-client-1.1:javaagent'
|
||||||
include ':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-common:javaagent'
|
include ':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-common:javaagent'
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
|
||||||
response.withCloseable {
|
response.withCloseable {
|
||||||
assert response.code() == REDIRECT.status
|
assert response.code() == REDIRECT.status
|
||||||
assert response.header("location") == REDIRECT.body ||
|
assert response.header("location") == REDIRECT.body ||
|
||||||
response.header("location") == "${address.resolve(REDIRECT.body)}"
|
new URI(response.header("location")).normalize().toString() == "${address.resolve(REDIRECT.body)}"
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue