This is an automated email from the ASF dual-hosted git repository. reta pushed a commit to branch 4.0.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit c0c324a325abecd5ee1bf9ba1171ffb9997a8d7c Author: Andriy Redko <[email protected]> AuthorDate: Sun Sep 28 14:44:59 2025 -0400 Add more tests for sync / async client to excercise parallel calls (cherry picked from commit f7be1cfcf7ffe1c7e0158dbaf97f383cc94c3d83) --- .../jaxrs/JAXRSAsyncClientChunkingTest.java | 41 ++++++++++++++++++ .../cxf/systest/jaxrs/JAXRSClientChunkingTest.java | 48 ++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSAsyncClientChunkingTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSAsyncClientChunkingTest.java index 8d754780d5..ad6e3d4baa 100644 --- a/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSAsyncClientChunkingTest.java +++ b/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSAsyncClientChunkingTest.java @@ -22,6 +22,7 @@ package org.apache.cxf.systest.jaxrs; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -29,6 +30,7 @@ import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; @@ -215,6 +217,45 @@ public class JAXRSAsyncClientChunkingTest extends AbstractBusClientServerTestBas assertNoDuplicateLogging(); } + + @Test + public void testStreamChunkingAsyncParallel() + throws IOException, InterruptedException, ExecutionException, TimeoutException { + final String url = "http://localhost:" + PORT + "/file-store/stream"; + final WebClient webClient = WebClient.create(url).query("chunked", chunked); + + final ClientConfiguration config = WebClient.getConfig(webClient); + config.getBus().setProperty(AsyncHTTPConduit.USE_ASYNC, true); + config.getHttpConduit().getClient().setAllowChunking(chunked); + config.getHttpConduit().getClient().setAutoRedirect(autoRedirect); + configureLogging(config); + + final byte[] bytes = new byte [32 * 1024]; + final Random random = new Random(); + random.nextBytes(bytes); + + final Collection<Future<Response>> futures = new ArrayList<>(); + try { + for (int i = 0; i < 100; ++i) { + try (InputStream in = new ByteArrayInputStream(bytes)) { + final Entity<InputStream> entity = Entity.entity(in, MediaType.APPLICATION_OCTET_STREAM); + futures.add(webClient.async().post(entity)); + } + } + + for (Future<Response> future: futures) { + try (Response response = future.get(10, TimeUnit.SECONDS)) { + assertThat(response.getStatus(), equalTo(200)); + assertThat(response.getHeaderString("Transfer-Encoding"), equalTo(chunked ? "chunked" : null)); + assertThat(response.getEntity(), not(equalTo(null))); + } + } + } finally { + webClient.close(); + } + + assertNoDuplicateLogging(); + } private void assertRedirect(String filename) { final String url = "http://localhost:" + PORT + "/file-store/redirect"; diff --git a/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientChunkingTest.java b/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientChunkingTest.java index 88e9b5d020..a8524da8c9 100644 --- a/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientChunkingTest.java +++ b/systests/transports/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientChunkingTest.java @@ -22,15 +22,23 @@ package org.apache.cxf.systest.jaxrs; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MultivaluedMap; import jakarta.ws.rs.core.Response; +import org.apache.cxf.jaxrs.client.ClientConfiguration; import org.apache.cxf.jaxrs.client.WebClient; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; @@ -113,4 +121,44 @@ public class JAXRSClientChunkingTest extends AbstractBusClientServerTestBase { webClient.close(); } } + + @Test + public void testStreamChunkingParallel() + throws IOException, InterruptedException, ExecutionException, TimeoutException { + final String url = "http://localhost:" + PORT + "/file-store/stream"; + final WebClient webClient = WebClient.create(url).query("chunked", chunked); + final ExecutorService pool = Executors.newFixedThreadPool(100); + + final ClientConfiguration config = WebClient.getConfig(webClient); + config.getHttpConduit().getClient().setAllowChunking(chunked); + + final byte[] bytes = new byte [32 * 1024]; + final Random random = new Random(); + random.nextBytes(bytes); + + final Collection<Future<Response>> futures = new ArrayList<>(); + try { + for (int i = 0; i < 100; ++i) { + try (InputStream in = new ByteArrayInputStream(bytes)) { + final Entity<InputStream> entity = Entity.entity(in, MediaType.APPLICATION_OCTET_STREAM); + futures.add(pool.submit(() -> webClient.post(entity))); + } + } + + for (Future<Response> future: futures) { + try (Response response = future.get(10, TimeUnit.SECONDS)) { + assertThat(response.getStatus(), equalTo(200)); + assertThat(response.getHeaderString("Transfer-Encoding"), equalTo(chunked ? "chunked" : null)); + assertThat(response.getEntity(), not(equalTo(null))); + } + } + } finally { + webClient.close(); + } + + pool.shutdown(); + if (!pool.awaitTermination(2, TimeUnit.MINUTES)) { + pool.shutdownNow(); + } + } }
