Support RESTeasy 4.0 version in unit tests (#1082)
* Support RESTeasy 4.0 version in unit tests * Split jaxrs-2.0 into jaxrs-2.0-common and jaxrs-2.0-testing (similar to e.g. play) * Support newest RESTEasy version in unit tests * Apply suggestions from code review Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com> * Support RESTeasy 4.0 version in unit tests - code review follow-up Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
266b8b927d
commit
9566315914
|
@ -4,14 +4,11 @@ ext {
|
|||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||
|
||||
dependencies {
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0')
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0')
|
||||
|
||||
// First version with DropwizardTestSupport:
|
||||
testImplementation group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.8.0'
|
||||
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
||||
testImplementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner', version: '2.9.10'
|
||||
|
||||
// Anything 1.0+ fails with a java.lang.NoClassDefFoundError: org/eclipse/jetty/server/RequestLog
|
||||
// latestDepTestLibrary group: 'io.dropwizard', name: 'dropwizard-testing', version: '1.+'
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||
|
||||
muzzle {
|
||||
fail {
|
||||
group = "javax.ws.rs"
|
||||
module = "jsr311-api"
|
||||
versions = "[,]"
|
||||
}
|
||||
pass {
|
||||
group = "javax.ws.rs"
|
||||
module = "javax.ws.rs-api"
|
||||
versions = "[,]"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||
}
|
|
@ -19,15 +19,14 @@ package io.opentelemetry.instrumentation.auto.jaxrs.v2_0;
|
|||
import static io.opentelemetry.instrumentation.auto.jaxrs.v2_0.JaxRsAnnotationsTracer.TRACER;
|
||||
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
|
||||
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
|
||||
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
|
||||
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 static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
|
||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -74,39 +73,39 @@ public abstract class AbstractRequestContextInstrumentation extends Instrumenter
|
|||
}
|
||||
|
||||
public static class RequestFilterHelper {
|
||||
public static SpanWithScope createOrUpdateAbortSpan(
|
||||
public static Span createOrUpdateAbortSpan(
|
||||
ContainerRequestContext context, Class<?> resourceClass, Method method) {
|
||||
|
||||
if (method != null && resourceClass != null) {
|
||||
context.setProperty(JaxRsAnnotationsTracer.ABORT_HANDLED, true);
|
||||
Span parent = BaseTracer.getCurrentServerSpan();
|
||||
Span span = TRACER.getCurrentSpan();
|
||||
Span serverSpan = BaseTracer.getCurrentServerSpan();
|
||||
Span currentSpan = TRACER.getCurrentSpan();
|
||||
|
||||
if (span == null) {
|
||||
span = TRACER.startSpan(resourceClass, method);
|
||||
return new SpanWithScope(span, currentContextWith(span));
|
||||
// if there's no current span or it's the same as the server (servlet) span we need to start
|
||||
// a JAX-RS one
|
||||
// in other case, DefaultRequestContextInstrumentation must have already run so it's enough
|
||||
// to just update the names
|
||||
if (currentSpan == null || currentSpan == serverSpan) {
|
||||
return TRACER.startSpan(resourceClass, method);
|
||||
} else {
|
||||
TRACER.updateSpanNames(span, parent, resourceClass, method);
|
||||
TRACER.updateSpanNames(currentSpan, serverSpan, resourceClass, method);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeSpanAndScope(SpanWithScope spanWithScope, Throwable throwable) {
|
||||
if (spanWithScope == null) {
|
||||
public static void closeSpanAndScope(Span span, Scope scope, Throwable throwable) {
|
||||
if (span == null || scope == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Span span = spanWithScope.getSpan();
|
||||
if (throwable != null) {
|
||||
TRACER.endExceptionally(span, throwable);
|
||||
} else {
|
||||
TRACER.end(span);
|
||||
}
|
||||
|
||||
spanWithScope.closeScope();
|
||||
scope.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,15 +17,15 @@
|
|||
package io.opentelemetry.instrumentation.auto.jaxrs.v2_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.auto.jaxrs.v2_0.JaxRsAnnotationsTracer.TRACER;
|
||||
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.asm.Advice.Local;
|
||||
|
||||
/**
|
||||
* Default context instrumentation.
|
||||
|
@ -40,10 +40,13 @@ import net.bytebuddy.asm.Advice;
|
|||
public class DefaultRequestContextInstrumentation extends AbstractRequestContextInstrumentation {
|
||||
public static class ContainerRequestContextAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static SpanWithScope createGenericSpan(@Advice.This ContainerRequestContext context) {
|
||||
|
||||
public static void createGenericSpan(
|
||||
@Advice.This ContainerRequestContext context,
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope) {
|
||||
if (context.getProperty(JaxRsAnnotationsTracer.ABORT_HANDLED) == null) {
|
||||
Class filterClass = (Class) context.getProperty(JaxRsAnnotationsTracer.ABORT_FILTER_CLASS);
|
||||
Class<?> filterClass =
|
||||
(Class<?>) context.getProperty(JaxRsAnnotationsTracer.ABORT_FILTER_CLASS);
|
||||
Method method = null;
|
||||
try {
|
||||
method = filterClass.getMethod("filter", ContainerRequestContext.class);
|
||||
|
@ -52,29 +55,17 @@ public class DefaultRequestContextInstrumentation extends AbstractRequestContext
|
|||
// can only be aborted inside the filter method
|
||||
}
|
||||
|
||||
Span span = TRACER.startSpan(filterClass, method);
|
||||
|
||||
return new SpanWithScope(span, currentContextWith(span));
|
||||
span = TRACER.startSpan(filterClass, method);
|
||||
scope = TRACER.startScope(span);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) {
|
||||
if (spanWithScope == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Span span = spanWithScope.getSpan();
|
||||
if (throwable != null) {
|
||||
TRACER.endExceptionally(span, throwable);
|
||||
} else {
|
||||
TRACER.end(span);
|
||||
}
|
||||
|
||||
spanWithScope.closeScope();
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(span, scope, throwable);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNa
|
|||
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.hasSuperMethod;
|
||||
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType;
|
||||
import static io.opentelemetry.javaagent.tooling.matcher.NameMatchers.namedOneOf;
|
||||
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.declaresMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith;
|
||||
|
@ -29,10 +28,10 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
|||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.auto.api.CallDepthThreadLocalMap;
|
||||
import io.opentelemetry.instrumentation.auto.api.ContextStore;
|
||||
import io.opentelemetry.instrumentation.auto.api.InstrumentationContext;
|
||||
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
|
||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -101,11 +100,13 @@ public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default
|
|||
public static class JaxRsAnnotationsAdvice {
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static SpanWithScope nameSpan(
|
||||
public static void nameSpan(
|
||||
@Advice.This Object target,
|
||||
@Advice.Origin Method method,
|
||||
@Advice.AllArguments Object[] args,
|
||||
@Advice.Local("asyncResponse") AsyncResponse asyncResponse) {
|
||||
@Advice.Local("otelSpan") Span span,
|
||||
@Advice.Local("otelScope") Scope scope,
|
||||
@Advice.Local("otelAsyncResponse") AsyncResponse asyncResponse) {
|
||||
ContextStore<AsyncResponse, Span> contextStore = null;
|
||||
for (Object arg : args) {
|
||||
if (arg instanceof AsyncResponse) {
|
||||
|
@ -118,39 +119,39 @@ public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default
|
|||
* could work around this by using a list instead, but we likely don't want the extra
|
||||
* span anyway.
|
||||
*/
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (CallDepthThreadLocalMap.incrementCallDepth(Path.class) > 0) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
Span span = TRACER.startSpan(target.getClass(), method);
|
||||
span = TRACER.startSpan(target.getClass(), method);
|
||||
|
||||
if (contextStore != null && asyncResponse != null) {
|
||||
contextStore.put(asyncResponse, span);
|
||||
}
|
||||
|
||||
return new SpanWithScope(span, currentContextWith(span));
|
||||
scope = TRACER.startScope(span);
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter SpanWithScope spanWithScope,
|
||||
@Advice.Thrown Throwable throwable,
|
||||
@Advice.Local("asyncResponse") AsyncResponse asyncResponse) {
|
||||
if (spanWithScope == null) {
|
||||
@Advice.Local("otelSpan") Span span,
|
||||
@Advice.Local("otelScope") Scope scope,
|
||||
@Advice.Local("otelAsyncResponse") AsyncResponse asyncResponse) {
|
||||
if (span == null || scope == null) {
|
||||
return;
|
||||
}
|
||||
CallDepthThreadLocalMap.reset(Path.class);
|
||||
|
||||
Span span = spanWithScope.getSpan();
|
||||
if (throwable != null) {
|
||||
TRACER.endExceptionally(span, throwable);
|
||||
spanWithScope.closeScope();
|
||||
scope.close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -161,7 +162,7 @@ public final class JaxRsAnnotationsInstrumentation extends Instrumenter.Default
|
|||
if (asyncResponse == null || !asyncResponse.isSuspended()) {
|
||||
TRACER.end(span);
|
||||
}
|
||||
spanWithScope.closeScope();
|
||||
scope.close();
|
||||
// else span finished by AsyncResponseAdvice
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package io.opentelemetry.instrumentation.auto.jaxrs.v2_0;
|
|||
|
||||
import static io.opentelemetry.instrumentation.auto.api.WeakMap.Provider.newWeakMap;
|
||||
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||
import io.opentelemetry.instrumentation.auto.api.WeakMap;
|
||||
import io.opentelemetry.javaagent.tooling.ClassHierarchyIterable;
|
||||
|
@ -59,6 +60,10 @@ public class JaxRsAnnotationsTracer extends BaseTracer {
|
|||
}
|
||||
}
|
||||
|
||||
public Scope startScope(Span span) {
|
||||
return tracer.withSpan(span);
|
||||
}
|
||||
|
||||
private void updateSpanName(Span span, String spanName) {
|
||||
if (!spanName.isEmpty()) {
|
||||
span.updateName(spanName);
|
|
@ -2,7 +2,7 @@ apply from: "$rootDir/gradle/instrumentation.gradle"
|
|||
|
||||
muzzle {
|
||||
// Cant assert fails because muzzle assumes all instrumentations will fail
|
||||
// Instrumentations in jaxrs-2.0 will pass
|
||||
// Instrumentations in jaxrs-2.0-common will pass
|
||||
pass {
|
||||
group = "org.glassfish.jersey.core"
|
||||
module = "jersey-server"
|
||||
|
@ -14,5 +14,13 @@ dependencies {
|
|||
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'
|
||||
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0')
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common')
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||
|
||||
// First version with DropwizardTestSupport:
|
||||
testLibrary group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.8.0'
|
||||
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
||||
testImplementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner', version: '2.9.10'
|
||||
}
|
||||
|
|
|
@ -16,14 +16,18 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.auto.jaxrs.v2_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.auto.jaxrs.v2_0.JaxRsAnnotationsTracer.TRACER;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ResourceInfo;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.asm.Advice.Local;
|
||||
|
||||
/**
|
||||
* Jersey specific context instrumentation.
|
||||
|
@ -38,7 +42,10 @@ import net.bytebuddy.asm.Advice;
|
|||
public class JerseyRequestContextInstrumentation extends AbstractRequestContextInstrumentation {
|
||||
public static class ContainerRequestContextAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static SpanWithScope decorateAbortSpan(@Advice.This ContainerRequestContext context) {
|
||||
public static void decorateAbortSpan(
|
||||
@Advice.This ContainerRequestContext context,
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope) {
|
||||
UriInfo uriInfo = context.getUriInfo();
|
||||
|
||||
if (context.getProperty(JaxRsAnnotationsTracer.ABORT_HANDLED) == null
|
||||
|
@ -46,18 +53,21 @@ public class JerseyRequestContextInstrumentation extends AbstractRequestContextI
|
|||
|
||||
ResourceInfo resourceInfo = (ResourceInfo) uriInfo;
|
||||
Method method = resourceInfo.getResourceMethod();
|
||||
Class resourceClass = resourceInfo.getResourceClass();
|
||||
Class<?> resourceClass = resourceInfo.getResourceClass();
|
||||
|
||||
return RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method);
|
||||
span = RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method);
|
||||
if (span != null) {
|
||||
scope = TRACER.startScope(span);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter SpanWithScope scope, @Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(scope, throwable);
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(span, scope, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class JerseyAnnotationInstrumentationTest extends JaxRsAnnotationsInstrumentationTest {
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static Resource.Test1
|
||||
import static Resource.Test2
|
||||
import static Resource.Test3
|
||||
|
||||
import io.dropwizard.testing.junit.ResourceTestRule
|
||||
import javax.ws.rs.client.Entity
|
||||
import javax.ws.rs.core.Response
|
||||
import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
|
||||
class JerseyFilterTest extends JaxRsFilterTest {
|
||||
@Shared
|
||||
@ClassRule
|
||||
ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addResource(new Test1())
|
||||
.addResource(new Test2())
|
||||
.addResource(new Test3())
|
||||
.addProvider(simpleRequestFilter)
|
||||
.addProvider(prematchRequestFilter)
|
||||
.build()
|
||||
|
||||
@Override
|
||||
def makeRequest(String url) {
|
||||
Response response = resources.client().target(url).request().post(Entity.text(""))
|
||||
|
||||
return [response.readEntity(String), response.statusInfo.statusCode]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import io.dropwizard.jetty.NonblockingServletHolder
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||
import org.glassfish.jersey.server.ResourceConfig
|
||||
import org.glassfish.jersey.servlet.ServletContainer
|
||||
|
||||
class JerseyHttpServerTest extends JaxRsHttpServerTest<Server> {
|
||||
|
||||
@Override
|
||||
Server startServer(int port) {
|
||||
def servlet = new ServletContainer(ResourceConfig.forApplicationClass(JaxRsTestApplication))
|
||||
|
||||
def handler = new ServletContextHandler(ServletContextHandler.SESSIONS)
|
||||
handler.setContextPath("/")
|
||||
handler.addServlet(new NonblockingServletHolder(servlet), "/*")
|
||||
|
||||
def server = new Server(port)
|
||||
server.setHandler(handler)
|
||||
server.start()
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(Server httpServer) {
|
||||
httpServer.stop()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ apply from: "$rootDir/gradle/instrumentation.gradle"
|
|||
|
||||
muzzle {
|
||||
// Cant assert fails because muzzle assumes all instrumentations will fail
|
||||
// Instrumentations in jaxrs-2.0 will pass
|
||||
// Instrumentations in jaxrs-2.0-common will pass
|
||||
|
||||
// Resteasy changes a class's package in 3.1.0 then moves it back in 3.5.0 and then moves it forward again in 4.0.0
|
||||
// so the jaxrs-2.0-resteasy-3.0 module applies to [3.0, 3.1) and [3.5, 4.0)
|
||||
|
@ -22,7 +22,20 @@ muzzle {
|
|||
|
||||
dependencies {
|
||||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||
compileOnly group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.0.0.Final'
|
||||
library group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.0.0.Final'
|
||||
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0')
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common')
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||
|
||||
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.0.4.Final') {
|
||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
}
|
||||
testLibrary group: 'io.undertow', name: 'undertow-servlet', version: '1.0.0.Final'
|
||||
|
||||
latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.+'
|
||||
latestDepTestLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.+') {
|
||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,16 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.auto.jaxrs.v2_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.auto.jaxrs.v2_0.JaxRsAnnotationsTracer.TRACER;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.asm.Advice.Local;
|
||||
import org.jboss.resteasy.core.ResourceMethodInvoker;
|
||||
import org.jboss.resteasy.core.interception.PostMatchContainerRequestContext;
|
||||
|
||||
|
@ -38,27 +42,32 @@ import org.jboss.resteasy.core.interception.PostMatchContainerRequestContext;
|
|||
@AutoService(Instrumenter.class)
|
||||
public class Resteasy30RequestContextInstrumentation extends AbstractRequestContextInstrumentation {
|
||||
public static class ContainerRequestContextAdvice {
|
||||
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static SpanWithScope decorateAbortSpan(@Advice.This ContainerRequestContext context) {
|
||||
public static void decorateAbortSpan(
|
||||
@Advice.This ContainerRequestContext context,
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope) {
|
||||
if (context.getProperty(JaxRsAnnotationsTracer.ABORT_HANDLED) == null
|
||||
&& context instanceof PostMatchContainerRequestContext) {
|
||||
|
||||
ResourceMethodInvoker resourceMethodInvoker =
|
||||
((PostMatchContainerRequestContext) context).getResourceMethod();
|
||||
Method method = resourceMethodInvoker.getMethod();
|
||||
Class resourceClass = resourceMethodInvoker.getResourceClass();
|
||||
Class<?> resourceClass = resourceMethodInvoker.getResourceClass();
|
||||
|
||||
return RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method);
|
||||
span = RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method);
|
||||
if (span != null) {
|
||||
scope = TRACER.startScope(span);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter SpanWithScope scope, @Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(scope, throwable);
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(span, scope, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class ResteasyAnnotationInstrumentationTest extends JaxRsAnnotationsInstrumentationTest {
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static Resource.Test1
|
||||
import static Resource.Test2
|
||||
import static Resource.Test3
|
||||
|
||||
import javax.ws.rs.core.MediaType
|
||||
import org.jboss.resteasy.mock.MockDispatcherFactory
|
||||
import org.jboss.resteasy.mock.MockHttpRequest
|
||||
import org.jboss.resteasy.mock.MockHttpResponse
|
||||
import spock.lang.Shared
|
||||
|
||||
class ResteasyFilterTest extends JaxRsFilterTest {
|
||||
@Shared
|
||||
def dispatcher
|
||||
|
||||
def setupSpec() {
|
||||
dispatcher = MockDispatcherFactory.createDispatcher()
|
||||
def registry = dispatcher.getRegistry()
|
||||
registry.addSingletonResource(new Test1())
|
||||
registry.addSingletonResource(new Test2())
|
||||
registry.addSingletonResource(new Test3())
|
||||
|
||||
dispatcher.getProviderFactory().register(simpleRequestFilter)
|
||||
dispatcher.getProviderFactory().register(prematchRequestFilter)
|
||||
}
|
||||
|
||||
@Override
|
||||
def makeRequest(String url) {
|
||||
MockHttpRequest request = MockHttpRequest.post(url)
|
||||
request.contentType(MediaType.TEXT_PLAIN_TYPE)
|
||||
request.content(new byte[0])
|
||||
|
||||
MockHttpResponse response = new MockHttpResponse()
|
||||
dispatcher.invoke(request, response)
|
||||
|
||||
return [response.contentAsString, response.status]
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import io.undertow.Undertow
|
||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
||||
|
||||
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
||||
|
||||
@Override
|
||||
UndertowJaxrsServer startServer(int port) {
|
||||
def server = new UndertowJaxrsServer()
|
||||
server.deploy(JaxRsTestApplication)
|
||||
server.start(Undertow.builder()
|
||||
.addHttpListener(port, "localhost"))
|
||||
return server
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(UndertowJaxrsServer server) {
|
||||
server.stop()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ apply from: "$rootDir/gradle/instrumentation.gradle"
|
|||
|
||||
muzzle {
|
||||
// Cant assert fails because muzzle assumes all instrumentations will fail
|
||||
// Instrumentations in jaxrs-2.0 will pass
|
||||
// Instrumentations in jaxrs-2.0-common will pass
|
||||
|
||||
// Resteasy changes a class's package in 3.1.0 then moves it back in 3.5.0 and then moves it forward again in 4.0.0
|
||||
// so the jaxrs-2.0-resteasy-3.0 module applies to [3.0, 3.1) and [3.5, 4.0)
|
||||
|
@ -22,7 +22,24 @@ muzzle {
|
|||
|
||||
dependencies {
|
||||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||
compileOnly group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.1.0.Final'
|
||||
library group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.1.0.Final'
|
||||
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0')
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common')
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing')
|
||||
|
||||
testLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.1.0.Final') {
|
||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
}
|
||||
|
||||
// artifact name changed from 'resteasy-jaxrs' to 'resteasy-core' starting from version 4.0.0
|
||||
latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-core', version: '+'
|
||||
}
|
||||
|
||||
if (findProperty('testLatestDeps')) {
|
||||
configurations {
|
||||
// artifact name changed from 'resteasy-jaxrs' to 'resteasy-core' starting from version 4.0.0
|
||||
testImplementation.exclude group: 'org.jboss.resteasy', module: 'resteasy-jaxrs'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,16 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.auto.jaxrs.v2_0;
|
||||
|
||||
import static io.opentelemetry.instrumentation.auto.jaxrs.v2_0.JaxRsAnnotationsTracer.TRACER;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import io.opentelemetry.instrumentation.auto.api.SpanWithScope;
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.javaagent.tooling.Instrumenter;
|
||||
import io.opentelemetry.trace.Span;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.asm.Advice.Local;
|
||||
import org.jboss.resteasy.core.ResourceMethodInvoker;
|
||||
import org.jboss.resteasy.core.interception.jaxrs.PostMatchContainerRequestContext;
|
||||
|
||||
|
@ -39,25 +43,31 @@ import org.jboss.resteasy.core.interception.jaxrs.PostMatchContainerRequestConte
|
|||
public class Resteasy31RequestContextInstrumentation extends AbstractRequestContextInstrumentation {
|
||||
public static class ContainerRequestContextAdvice {
|
||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||
public static SpanWithScope decorateAbortSpan(@Advice.This ContainerRequestContext context) {
|
||||
public static void decorateAbortSpan(
|
||||
@Advice.This ContainerRequestContext context,
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope) {
|
||||
if (context.getProperty(JaxRsAnnotationsTracer.ABORT_HANDLED) == null
|
||||
&& context instanceof PostMatchContainerRequestContext) {
|
||||
|
||||
ResourceMethodInvoker resourceMethodInvoker =
|
||||
((PostMatchContainerRequestContext) context).getResourceMethod();
|
||||
Method method = resourceMethodInvoker.getMethod();
|
||||
Class resourceClass = resourceMethodInvoker.getResourceClass();
|
||||
Class<?> resourceClass = resourceMethodInvoker.getResourceClass();
|
||||
|
||||
return RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method);
|
||||
span = RequestFilterHelper.createOrUpdateAbortSpan(context, resourceClass, method);
|
||||
if (span != null) {
|
||||
scope = TRACER.startScope(span);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Enter SpanWithScope scope, @Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(scope, throwable);
|
||||
@Local("otelSpan") Span span,
|
||||
@Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
RequestFilterHelper.closeSpanAndScope(span, scope, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class ResteasyAnnotationInstrumentationTest extends JaxRsAnnotationsInstrumentationTest {
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import static Resource.Test1
|
||||
import static Resource.Test2
|
||||
import static Resource.Test3
|
||||
|
||||
import javax.ws.rs.core.MediaType
|
||||
import org.jboss.resteasy.mock.MockDispatcherFactory
|
||||
import org.jboss.resteasy.mock.MockHttpRequest
|
||||
import org.jboss.resteasy.mock.MockHttpResponse
|
||||
import spock.lang.Shared
|
||||
|
||||
class ResteasyFilterTest extends JaxRsFilterTest {
|
||||
@Shared
|
||||
def dispatcher
|
||||
|
||||
def setupSpec() {
|
||||
dispatcher = MockDispatcherFactory.createDispatcher()
|
||||
def registry = dispatcher.getRegistry()
|
||||
registry.addSingletonResource(new Test1())
|
||||
registry.addSingletonResource(new Test2())
|
||||
registry.addSingletonResource(new Test3())
|
||||
|
||||
dispatcher.getProviderFactory().register(simpleRequestFilter)
|
||||
dispatcher.getProviderFactory().register(prematchRequestFilter)
|
||||
}
|
||||
|
||||
@Override
|
||||
def makeRequest(String url) {
|
||||
MockHttpRequest request = MockHttpRequest.post(url)
|
||||
request.contentType(MediaType.TEXT_PLAIN_TYPE)
|
||||
request.content(new byte[0])
|
||||
|
||||
MockHttpResponse response = new MockHttpResponse()
|
||||
dispatcher.invoke(request, response)
|
||||
|
||||
return [response.contentAsString, response.status]
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import io.undertow.Undertow
|
||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
||||
|
||||
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
||||
|
||||
@Override
|
||||
UndertowJaxrsServer startServer(int port) {
|
||||
def server = new UndertowJaxrsServer()
|
||||
server.deploy(JaxRsTestApplication)
|
||||
server.start(Undertow.builder()
|
||||
.addHttpListener(port, "localhost"))
|
||||
return server
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(UndertowJaxrsServer server) {
|
||||
server.stop()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
apply from: "$rootDir/gradle/java.gradle"
|
||||
|
||||
dependencies {
|
||||
api project(':testing-common')
|
||||
api group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||
|
||||
implementation deps.groovy
|
||||
implementation deps.opentelemetryApi
|
||||
implementation deps.spock
|
||||
implementation deps.slf4j
|
||||
implementation deps.testLogging
|
||||
|
||||
implementation project(':auto-api')
|
||||
implementation project(':instrumentation-api')
|
||||
implementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common')
|
||||
}
|
|
@ -28,7 +28,7 @@ import javax.ws.rs.POST
|
|||
import javax.ws.rs.PUT
|
||||
import javax.ws.rs.Path
|
||||
|
||||
class JaxRsAnnotations2InstrumentationTest extends AgentTestRunner {
|
||||
abstract class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {
|
||||
|
||||
def "instrumentation can be used as root span and resource is set to METHOD PATH"() {
|
||||
setup:
|
|
@ -17,20 +17,13 @@
|
|||
import static io.opentelemetry.auto.test.utils.TraceUtils.runUnderServerTrace
|
||||
import static io.opentelemetry.trace.Span.Kind.INTERNAL
|
||||
|
||||
import io.dropwizard.testing.junit.ResourceTestRule
|
||||
import io.opentelemetry.auto.test.AgentTestRunner
|
||||
import javax.ws.rs.client.Entity
|
||||
import javax.ws.rs.container.ContainerRequestContext
|
||||
import javax.ws.rs.container.ContainerRequestFilter
|
||||
import javax.ws.rs.container.PreMatching
|
||||
import javax.ws.rs.core.MediaType
|
||||
import javax.ws.rs.core.Response
|
||||
import javax.ws.rs.ext.Provider
|
||||
import org.jboss.resteasy.core.Dispatcher
|
||||
import org.jboss.resteasy.mock.MockDispatcherFactory
|
||||
import org.jboss.resteasy.mock.MockHttpRequest
|
||||
import org.jboss.resteasy.mock.MockHttpResponse
|
||||
import org.junit.ClassRule
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Unroll
|
||||
|
||||
|
@ -52,12 +45,9 @@ abstract class JaxRsFilterTest extends AgentTestRunner {
|
|||
def abort = abortNormal || abortPrematch
|
||||
|
||||
when:
|
||||
def responseText
|
||||
def responseStatus
|
||||
|
||||
// start a trace because the test doesn't go through any servlet or other instrumentation.
|
||||
runUnderServerTrace("test.span") {
|
||||
(responseText, responseStatus) = makeRequest(resource)
|
||||
def (responseText, responseStatus) = runUnderServerTrace("test.span") {
|
||||
makeRequest(resource)
|
||||
}
|
||||
|
||||
then:
|
||||
|
@ -109,12 +99,9 @@ abstract class JaxRsFilterTest extends AgentTestRunner {
|
|||
prematchRequestFilter.abort = false
|
||||
|
||||
when:
|
||||
def responseText
|
||||
def responseStatus
|
||||
|
||||
// start a trace because the test doesn't go through any servlet or other instrumentation.
|
||||
runUnderServerTrace("test.span") {
|
||||
(responseText, responseStatus) = makeRequest(resource)
|
||||
def (responseText, responseStatus) = runUnderServerTrace("test.span") {
|
||||
makeRequest(resource)
|
||||
}
|
||||
|
||||
then:
|
||||
|
@ -176,51 +163,3 @@ abstract class JaxRsFilterTest extends AgentTestRunner {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JerseyFilterTest extends JaxRsFilterTest {
|
||||
@Shared
|
||||
@ClassRule
|
||||
ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addResource(new Resource.Test1())
|
||||
.addResource(new Resource.Test2())
|
||||
.addResource(new Resource.Test3())
|
||||
.addProvider(simpleRequestFilter)
|
||||
.addProvider(prematchRequestFilter)
|
||||
.build()
|
||||
|
||||
@Override
|
||||
def makeRequest(String url) {
|
||||
Response response = resources.client().target(url).request().post(Entity.text(""))
|
||||
|
||||
return [response.readEntity(String), response.statusInfo.statusCode]
|
||||
}
|
||||
}
|
||||
|
||||
class ResteasyFilterTest extends JaxRsFilterTest {
|
||||
@Shared
|
||||
Dispatcher dispatcher
|
||||
|
||||
def setupSpec() {
|
||||
dispatcher = MockDispatcherFactory.createDispatcher()
|
||||
def registry = dispatcher.getRegistry()
|
||||
registry.addSingletonResource(new Resource.Test1())
|
||||
registry.addSingletonResource(new Resource.Test2())
|
||||
registry.addSingletonResource(new Resource.Test3())
|
||||
|
||||
dispatcher.getProviderFactory().register(simpleRequestFilter)
|
||||
dispatcher.getProviderFactory().register(prematchRequestFilter)
|
||||
}
|
||||
|
||||
@Override
|
||||
def makeRequest(String url) {
|
||||
MockHttpRequest request = MockHttpRequest.post(url)
|
||||
request.contentType(MediaType.TEXT_PLAIN_TYPE)
|
||||
request.content(new byte[0])
|
||||
|
||||
MockHttpResponse response = new MockHttpResponse()
|
||||
dispatcher.invoke(request, response)
|
||||
|
||||
return [response.contentAsString, response.status]
|
||||
}
|
||||
|
||||
}
|
|
@ -20,19 +20,12 @@ import static io.opentelemetry.auto.test.base.HttpServerTest.ServerEndpoint.SUCC
|
|||
import static io.opentelemetry.trace.Span.Kind.INTERNAL
|
||||
import static io.opentelemetry.trace.Span.Kind.SERVER
|
||||
|
||||
import io.dropwizard.jetty.NonblockingServletHolder
|
||||
import io.opentelemetry.auto.test.asserts.TraceAssert
|
||||
import io.opentelemetry.auto.test.base.HttpServerTest
|
||||
import io.opentelemetry.instrumentation.api.MoreAttributes
|
||||
import io.opentelemetry.sdk.trace.data.SpanData
|
||||
import io.opentelemetry.trace.attributes.SemanticAttributes
|
||||
import io.undertow.Undertow
|
||||
import okhttp3.HttpUrl
|
||||
import org.eclipse.jetty.server.Server
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||
import org.glassfish.jersey.server.ResourceConfig
|
||||
import org.glassfish.jersey.servlet.ServletContainer
|
||||
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer
|
||||
import spock.lang.Unroll
|
||||
|
||||
abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> {
|
||||
|
@ -184,42 +177,4 @@ abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> {
|
|||
}
|
||||
}
|
||||
|
||||
class ResteasyHttpServerTest extends JaxRsHttpServerTest<UndertowJaxrsServer> {
|
||||
|
||||
@Override
|
||||
UndertowJaxrsServer startServer(int port) {
|
||||
def server = new UndertowJaxrsServer()
|
||||
server.deploy(JaxRsTestApplication)
|
||||
server.start(Undertow.builder()
|
||||
.addHttpListener(port, "localhost"))
|
||||
return server
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(UndertowJaxrsServer server) {
|
||||
server.stop()
|
||||
}
|
||||
}
|
||||
|
||||
class JerseyHttpServerTest extends JaxRsHttpServerTest<Server> {
|
||||
|
||||
@Override
|
||||
Server startServer(int port) {
|
||||
def servlet = new ServletContainer(ResourceConfig.forApplicationClass(JaxRsTestApplication))
|
||||
|
||||
def handler = new ServletContextHandler(ServletContextHandler.SESSIONS)
|
||||
handler.setContextPath("/")
|
||||
handler.addServlet(new NonblockingServletHolder(servlet), "/*")
|
||||
|
||||
def server = new Server(port)
|
||||
server.setHandler(handler)
|
||||
server.start()
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
@Override
|
||||
void stopServer(Server httpServer) {
|
||||
httpServer.stop()
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
apply from: "$rootDir/gradle/instrumentation.gradle"
|
||||
apply plugin: 'org.unbroken-dome.test-sets'
|
||||
|
||||
muzzle {
|
||||
fail {
|
||||
group = "javax.ws.rs"
|
||||
module = "jsr311-api"
|
||||
versions = "[,]"
|
||||
}
|
||||
pass {
|
||||
group = "javax.ws.rs"
|
||||
module = "javax.ws.rs-api"
|
||||
versions = "[,]"
|
||||
}
|
||||
}
|
||||
|
||||
testSets {
|
||||
resteasy31Test {
|
||||
dirName = 'test'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0'
|
||||
|
||||
testImplementation project(':instrumentation:servlet:servlet-3.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.0')
|
||||
testImplementation project(':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.1')
|
||||
|
||||
// Jersey
|
||||
// First version with DropwizardTestSupport:
|
||||
testLibrary group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.8.0'
|
||||
testImplementation group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
|
||||
testImplementation group: 'com.fasterxml.jackson.module', name: 'jackson-module-afterburner', version: '2.9.10'
|
||||
|
||||
latestDepTestLibrary group: 'io.dropwizard', name: 'dropwizard-testing', version: '1.+'
|
||||
|
||||
// Resteasy
|
||||
testLibrary group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.0.0.Final'
|
||||
testImplementation(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.0.4.Final') {
|
||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
}
|
||||
testImplementation group: 'io.undertow', name: 'undertow-servlet', version: '1.0.0.Final'
|
||||
|
||||
resteasy31TestImplementation(group: 'org.jboss.resteasy', name: 'resteasy-jaxrs', version: '3.1.0.Final')
|
||||
resteasy31TestImplementation(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.1.0.Final') {
|
||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
}
|
||||
|
||||
latestDepTestLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '3.+') {
|
||||
exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
}
|
||||
|
||||
// TODO: resteasy 4.+ has changed artifact name to resteasy-core
|
||||
// latestDepTestLibrary group: 'org.jboss.resteasy', name: 'resteasy-core', version: '+'
|
||||
// latestDepTestLibrary(group: 'org.jboss.resteasy', name: 'resteasy-undertow', version: '+') {
|
||||
// exclude group: 'org.jboss.resteasy', module: 'resteasy-client'
|
||||
// }
|
||||
}
|
||||
|
||||
test.dependsOn resteasy31Test
|
|
@ -100,10 +100,11 @@ include ':instrumentation:java-classloader:tomcat-testing'
|
|||
include ':instrumentation:java-concurrent'
|
||||
include ':instrumentation:java-httpclient'
|
||||
include ':instrumentation:jaxrs:jaxrs-1.0'
|
||||
include ':instrumentation:jaxrs:jaxrs-2.0'
|
||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-common'
|
||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-jersey-2.0'
|
||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.0'
|
||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-resteasy-3.1'
|
||||
include ':instrumentation:jaxrs:jaxrs-2.0:jaxrs-2.0-testing'
|
||||
include ':instrumentation:jaxrs-client:jaxrs-client-1.1'
|
||||
include ':instrumentation:jaxrs-client:jaxrs-client-2.0'
|
||||
include ':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-jersey-2.0'
|
||||
|
|
Loading…
Reference in New Issue