From 6a8e80ec625f2ce9a7585dc45e645fab61aa504c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Haasler=20Garc=C3=ADa?= Date: Tue, 15 Sep 2020 18:32:24 +0200 Subject: [PATCH] Add test for concurrent custom SSLSocketFactory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test made by Kevin Conaway @kevinconaway Also-by: Kevin Conaway Signed-off-by: Adrian Haasler GarcĂ­a --- .../ssl/SslHttpUrlConnectorTest.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java index 7a823214a9..d7857bbc38 100644 --- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java +++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java @@ -17,10 +17,18 @@ package org.glassfish.jersey.tests.e2e.client.connector.ssl; import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.Socket; import java.net.URL; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; @@ -79,6 +87,61 @@ public HttpURLConnection getConnection(final URL url) throws IOException { assertTrue(socketFactory.isVisited()); } + /** + * Test for https://github.com/jersey/jersey/issues/3293 + * + * @author Kevin Conaway + */ + @Test + public void testConcurrentRequestsWithCustomSSLContext() throws Exception { + final SSLContext sslContext = getSslContext(); + + final Client client = ClientBuilder.newBuilder() + .sslContext(sslContext) + .register(HttpAuthenticationFeature.basic("user", "password")) + .register(LoggingFeature.class) + .build(); + + int numThreads = 5; + CyclicBarrier barrier = new CyclicBarrier(numThreads); + ExecutorService service = Executors.newFixedThreadPool(numThreads); + List exceptions = new CopyOnWriteArrayList<>(); + + for (int i = 0; i < numThreads; i++) { + service.submit(() -> { + try { + barrier.await(1, TimeUnit.MINUTES); + for (int call = 0; call < 10; call++) { + final Response response = client.target(Server.BASE_URI).path("/").request().get(); + assertEquals(200, response.getStatus()); + } + } catch (Exception ex) { + exceptions.add(ex); + } + }); + } + + service.shutdown(); + + assertTrue( + service.awaitTermination(1, TimeUnit.MINUTES) + ); + + assertTrue( + toString(exceptions), + exceptions.isEmpty() + ); + } + + private String toString(List exceptions) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + + exceptions.forEach(e -> e.printStackTrace(printWriter)); + + return writer.toString(); + } + public static class CustomSSLSocketFactory extends SSLSocketFactory { private boolean visited = false;