From 2df89e238897c29b2bbb4083070b00637a1b8603 Mon Sep 17 00:00:00 2001 From: Croway Date: Mon, 27 Jan 2025 15:51:17 +0100 Subject: [PATCH] Do not spawn useslss threads --- .../SpringBootPlatformHttpConsumer.java | 43 +++++++++---------- .../SpringBootPlatformHttpEngine.java | 2 +- ...ringBootPlatformHttpCertificationTest.java | 19 +++++++- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpConsumer.java b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpConsumer.java index 3da18e89aa4..f906c77320e 100644 --- a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpConsumer.java +++ b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpConsumer.java @@ -17,8 +17,7 @@ package org.apache.camel.component.platform.http.springboot; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; +import java.util.concurrent.Future; import jakarta.servlet.ServletException; import jakarta.servlet.http.Cookie; @@ -41,6 +40,8 @@ import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.context.request.RequestContextHolder; public class SpringBootPlatformHttpConsumer extends DefaultConsumer implements PlatformHttpConsumer, Suspendable, SuspendableService { @@ -48,7 +49,6 @@ public class SpringBootPlatformHttpConsumer extends DefaultConsumer implements P private HttpBinding binding; private final boolean handleWriteResponseError; - private Executor executor; private CookieConfiguration cookieConfiguration; public SpringBootPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor processor) { @@ -59,12 +59,6 @@ public SpringBootPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor p this.binding.setFileNameExtWhitelist(endpoint.getFileNameExtWhitelist()); this.binding.setUseReaderForPayload(!endpoint.isUseStreaming()); this.handleWriteResponseError = endpoint.isHandleWriteResponseError(); - this.executor = Executors.newSingleThreadExecutor(); - } - - public SpringBootPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor processor, Executor executor) { - this(endpoint, processor); - this.executor = executor; } /** @@ -80,26 +74,29 @@ public PlatformHttpEndpoint getEndpoint() { } /** - * This method is invoked by Spring Boot when invoking Camel via platform-http + * This method is invoked by Spring Boot when invoking Camel via platform-http. + * + * The method is already running asynchronously via AsyncExecutionInterceptor. + * + * Returns an empty CompletableFuture as per documentation https://spring.io/guides/gs/async-method */ @ResponseBody public CompletableFuture service(HttpServletRequest request, HttpServletResponse response) { - return CompletableFuture.runAsync(() -> { - LOG.trace("Service: {}", request); + LOG.trace("Service: {}", request); + try { + handleService(request, response); + } catch (Exception e) { + // do not leak exception back to caller + LOG.warn("Error handling request due to: {}", e.getMessage(), e); try { - handleService(request, response); - } catch (Exception e) { - // do not leak exception back to caller - LOG.warn("Error handling request due to: {}", e.getMessage(), e); - try { - if (!response.isCommitted()) { - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - } catch (Exception e1) { - // ignore + if (!response.isCommitted()) { + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } + } catch (Exception e1) { + // ignore } - }, executor); + } + return CompletableFuture.completedFuture(null); } protected void handleService(HttpServletRequest request, HttpServletResponse response) throws Exception { diff --git a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngine.java b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngine.java index 4e5d3c9ab16..dde685cb1a8 100644 --- a/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngine.java +++ b/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpEngine.java @@ -44,7 +44,7 @@ public SpringBootPlatformHttpEngine(int port, Executor executor) { @Override public PlatformHttpConsumer createConsumer(PlatformHttpEndpoint endpoint, Processor processor) { ProxyFactory factory = new ProxyFactory(); - factory.setTarget(new SpringBootPlatformHttpConsumer(endpoint, processor, executor)); + factory.setTarget(new SpringBootPlatformHttpConsumer(endpoint, processor)); JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut(); jdkRegexpMethodPointcut.setPattern("org.apache.camel.component.platform.http.springboot.SpringBootPlatformHttpConsumer.service"); diff --git a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java index 8f44699417b..4ddf6722a48 100644 --- a/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java +++ b/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpCertificationTest.java @@ -23,8 +23,15 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import io.restassured.RestAssured; import io.restassured.http.ContentType; @@ -179,8 +186,18 @@ protected String getGetRouteId() { public void testLoad() throws Exception { waitUntilRouteIsStarted(1, getGetRouteId()); + ExecutorService es = Executors.newFixedThreadPool(10); + List tasks = new ArrayList(); for (int i = 0; i < 1_000; i++) { - Assertions.assertThat(restTemplate.getForEntity("/myget", String.class).getStatusCode().value()).isEqualTo(200); + tasks.add(CompletableFuture.runAsync(() -> + Assertions.assertThat(restTemplate.getForEntity("/myget", String.class) + .getStatusCode().value()).isEqualTo(200), es)); + } + for (CompletableFuture task : tasks) { + task.get(); + if (task.isCompletedExceptionally()) { + org.junit.jupiter.api.Assertions.fail("Exception thrown during execution, check logs"); + } } }