137 lines
4.2 KiB
Groovy
137 lines
4.2 KiB
Groovy
import datadog.trace.agent.test.AgentTestRunner
|
|
import datadog.trace.agent.test.TestUtils
|
|
import datadog.trace.api.DDSpanTypes
|
|
import datadog.trace.api.DDTags
|
|
import io.opentracing.tag.Tags
|
|
import org.apache.cxf.jaxrs.client.spec.ClientBuilderImpl
|
|
import org.glassfish.jersey.client.JerseyClientBuilder
|
|
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder
|
|
import spock.lang.AutoCleanup
|
|
import spock.lang.Shared
|
|
|
|
import javax.ws.rs.ProcessingException
|
|
import javax.ws.rs.client.AsyncInvoker
|
|
import javax.ws.rs.client.Client
|
|
import javax.ws.rs.client.Invocation
|
|
import javax.ws.rs.client.WebTarget
|
|
import javax.ws.rs.core.MediaType
|
|
import javax.ws.rs.core.Response
|
|
import java.util.concurrent.ExecutionException
|
|
|
|
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
|
|
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
|
|
|
|
class JaxRsClientTest extends AgentTestRunner {
|
|
|
|
@Shared
|
|
def emptyPort = TestUtils.randomOpenPort()
|
|
|
|
@AutoCleanup
|
|
@Shared
|
|
def server = httpServer {
|
|
handlers {
|
|
all {
|
|
response.status(200).send("pong")
|
|
}
|
|
}
|
|
}
|
|
|
|
def "#lib request creates spans and sends headers"() {
|
|
setup:
|
|
Client client = builder.build()
|
|
WebTarget service = client.target("$server.address/ping")
|
|
Response response
|
|
if (async) {
|
|
AsyncInvoker request = service.request(MediaType.TEXT_PLAIN).async()
|
|
response = request.get().get()
|
|
} else {
|
|
Invocation.Builder request = service.request(MediaType.TEXT_PLAIN)
|
|
response = request.get()
|
|
}
|
|
|
|
expect:
|
|
response.readEntity(String) == "pong"
|
|
|
|
assertTraces(TEST_WRITER, 1) {
|
|
trace(0, 1) {
|
|
span(0) {
|
|
serviceName "unnamed-java-app"
|
|
resourceName "GET /ping"
|
|
operationName "jax-rs.client.call"
|
|
spanType "http"
|
|
parent()
|
|
errored false
|
|
tags {
|
|
|
|
"$Tags.COMPONENT.key" "jax-rs.client"
|
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
|
"$Tags.HTTP_METHOD.key" "GET"
|
|
"$Tags.HTTP_STATUS.key" 200
|
|
"$Tags.HTTP_URL.key" "$server.address/ping"
|
|
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
|
|
defaultTags()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
server.lastRequest.headers.get("x-datadog-trace-id") == TEST_WRITER[0][0].traceId
|
|
server.lastRequest.headers.get("x-datadog-parent-id") == TEST_WRITER[0][0].spanId
|
|
|
|
where:
|
|
builder | async | lib
|
|
new JerseyClientBuilder() | false | "jersey"
|
|
new ClientBuilderImpl() | false | "cxf"
|
|
new ResteasyClientBuilder() | false | "resteasy"
|
|
new JerseyClientBuilder() | true | "jersey async"
|
|
new ClientBuilderImpl() | true | "cxf async"
|
|
new ResteasyClientBuilder() | true | "resteasy async"
|
|
}
|
|
|
|
def "#lib connection failure creates errored span"() {
|
|
when:
|
|
Client client = builder.build()
|
|
WebTarget service = client.target("http://localhost:$emptyPort/ping")
|
|
if (async) {
|
|
AsyncInvoker request = service.request(MediaType.TEXT_PLAIN).async()
|
|
request.get().get()
|
|
} else {
|
|
Invocation.Builder request = service.request(MediaType.TEXT_PLAIN)
|
|
request.get()
|
|
}
|
|
|
|
then:
|
|
thrown async ? ExecutionException : ProcessingException
|
|
|
|
assertTraces(TEST_WRITER, 1) {
|
|
trace(0, 1) {
|
|
span(0) {
|
|
serviceName "unnamed-java-app"
|
|
resourceName "GET /ping"
|
|
operationName "jax-rs.client.call"
|
|
spanType "http"
|
|
parent()
|
|
errored true
|
|
tags {
|
|
"$Tags.COMPONENT.key" "jax-rs.client"
|
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
|
"$Tags.HTTP_METHOD.key" "GET"
|
|
"$Tags.HTTP_URL.key" "http://localhost:$emptyPort/ping"
|
|
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
|
|
errorTags ProcessingException, String
|
|
defaultTags()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
where:
|
|
builder | async | lib
|
|
new JerseyClientBuilder() | false | "jersey"
|
|
new ResteasyClientBuilder() | false | "resteasy"
|
|
new JerseyClientBuilder() | true | "jersey async"
|
|
new ResteasyClientBuilder() | true | "resteasy async"
|
|
// Unfortunately there's not a good way to instrument this for CXF.
|
|
}
|
|
}
|