JAX-RS RestEasy single connection test, comment on others where not applicable
MODIFY
instrumentation/async-http-client/async-http-client-1.9/javaagent/src/test/groovy/AsyncHttpClientTest.groovy
instrumentation/async-http-client/async-http-client-1.9/javaagent/src/test/groovy/AsyncHttpClientTest.groovy
@@ -12,6 +12,7 @@ import com.ning.http.client.Response
import com.ning.http.client.uri.Uri
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.test.base.HttpClientTest
+import io.opentelemetry.instrumentation.test.base.SingleConnection
import spock.lang.AutoCleanup
import spock.lang.Shared
@@ -63,6 +64,15 @@ class AsyncHttpClientTest extends HttpClientTest<Request> implements AgentTestTr
boolean testHttps() {
false
}
+
+ @Override
+ SingleConnection createSingleConnection(String host, int port) {
+ // AsyncHttpClient does not support HTTP 1.1 pipelining nor waiting for connection pool slots to
+ // free up (it immediately throws "Too many connections" IOException). Therefore making a single
+ // connection test would require manually sequencing the connections, which is not meaningful
+ // for a high concurrency test.
+ return null
+ }
}

MODIFY
instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-common/javaagent/src/test/groovy/JaxRsClientTest.groovy
instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-common/javaagent/src/test/groovy/JaxRsClientTest.groovy
@@ -9,6 +9,7 @@ import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTr
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.test.base.HttpClientTest
+import io.opentelemetry.instrumentation.test.base.SingleConnection
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import java.util.concurrent.TimeUnit
import javax.ws.rs.ProcessingException
@@ -128,6 +129,15 @@ class JerseyClientTest extends JaxRsClientTest {
int maxRedirects() {
20
}
+
+ @Override
+ SingleConnection createSingleConnection(String host, int port) {
+ // Jersey JAX-RS client uses HttpURLConnection internally, which does not support pipelining nor
+ // waiting for a connection in the pool to become available. Therefore a high concurrency test
+ // would require manually doing requests one after another which is not meaningful for a high
+ // concurrency test.
+ return null
+ }
}
class ResteasyClientTest extends JaxRsClientTest {
@@ -141,6 +151,11 @@ class ResteasyClientTest extends JaxRsClientTest {
boolean testRedirects() {
false
}
+
+ @Override
+ SingleConnection createSingleConnection(String host, int port) {
+ return new ResteasySingleConnection(host, port)
+ }
}
class CxfClientTest extends JaxRsClientTest {
@@ -154,4 +169,13 @@ class CxfClientTest extends JaxRsClientTest {
boolean testRedirects() {
false
}
+
+ @Override
+ SingleConnection createSingleConnection(String host, int port) {
+ // CXF JAX-RS client uses HttpURLConnection internally, which does not support pipelining nor
+ // waiting for a connection in the pool to become available. Therefore a high concurrency test
+ // would require manually doing requests one after another which is not meaningful for a high
+ // concurrency test.
+ return null
+ }
}

ADD
instrumentation/jaxrs-client/jaxrs-client-2.0/jaxrs-client-2.0-common/javaagent/src/test/groovy/ResteasySingleConnection.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import io.opentelemetry.instrumentation.test.base.SingleConnection
+import java.util.concurrent.ExecutionException
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
+import javax.ws.rs.core.MediaType
+import org.apache.http.client.params.ClientPNames
+import org.jboss.resteasy.client.jaxrs.ResteasyClient
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder
+import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine
+
+class ResteasySingleConnection implements SingleConnection {
+ private final ResteasyClient client
+ private final String host
+ private final int port
+
+ ResteasySingleConnection(String host, int port) {
+ this.host = host
+ this.port = port
+ this.client = new ResteasyClientBuilder()
+ .establishConnectionTimeout(5000, TimeUnit.MILLISECONDS)
+ .connectionPoolSize(1)
+ .build()
+
+ ((ApacheHttpClient4Engine) client.httpEngine()).httpClient.params
+ .setParameter(ClientPNames.CONN_MANAGER_TIMEOUT, 20000L)
+ }
+
+ @Override
+ int doRequest(String path, Map<String, String> headers) throws ExecutionException, InterruptedException, TimeoutException {
+ String requestId = Objects.requireNonNull(headers.get(REQUEST_ID_HEADER))
+
+ URI uri
+ try {
+ uri = new URL("http", host, port, path).toURI()
+ } catch (MalformedURLException e) {
+ throw new ExecutionException(e)
+ }
+
+ def requestBuilder = client.target(uri).request(MediaType.TEXT_PLAIN)
+ headers.each { requestBuilder.header(it.key, it.value) }
+
+ def response = requestBuilder.buildGet().invoke()
+ response.close()
+
+ String responseId = response.getHeaderString(REQUEST_ID_HEADER)
+ if (requestId != responseId) {
+ throw new IllegalStateException(
+ String.format("Received response with id %s, expected %s", responseId, requestId))
+ }
+
+ return response.getStatus()
+ }
+}

MODIFY
instrumentation/play/play-2.4/javaagent/src/test/groovy/client/PlayWsClientTest.groovy
instrumentation/play/play-2.4/javaagent/src/test/groovy/client/PlayWsClientTest.groovy
@@ -7,6 +7,8 @@ package client
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.test.base.HttpClientTest
+import io.opentelemetry.instrumentation.test.base.SingleConnection
+
import java.util.concurrent.CompletionStage
import play.libs.ws.WS
import play.libs.ws.WSRequest
@@ -63,4 +65,13 @@ class PlayWsClientTest extends HttpClientTest<WSRequest> implements AgentTestTra
boolean testHttps() {
false
}
+
+ @Override
+ SingleConnection createSingleConnection(String host, int port) {
+ // Play HTTP client uses AsyncHttpClient internally which does not support HTTP 1.1 pipelining
+ // nor waiting for connection pool slots to free up. Therefore making a single connection test
+ // would require manually sequencing the connections, which is not meaningful for a high
+ // concurrency test.
+ return null
+ }
}

JAX-RS RestEasy single connection test, comment on others where not applicable (#3187)