This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new cdf2960a6bb7 CAMEL-26606: camel-platform-http-vertx - fail the start
when the HTTP server cannot bind its port (#29221)
cdf2960a6bb7 is described below
commit cdf2960a6bb7b85763af9d94f2eda07ae9c8b718
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Nov 5 16:48:15 2026 +0100
CAMEL-26606: camel-platform-http-vertx - fail the start when the HTTP
server cannot bind its port (#29221)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Andrea Cosentino <[email protected]>
---
.../http/vertx/VertxPlatformHttpServer.java | 26 ++++++---
.../VertxPlatformHttpServerPortInUseTest.java | 67 ++++++++++++++++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 9 +++
3 files changed, 93 insertions(+), 9 deletions(-)
diff --git
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
index 9a03036a69d6..98d0195f7447 100644
---
a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
+++
b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServer.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.platform.http.vertx;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicReference;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
@@ -29,6 +30,7 @@ import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
+import org.apache.camel.RuntimeCamelException;
import org.apache.camel.StaticService;
import org.apache.camel.api.management.ManagedAttribute;
import org.apache.camel.api.management.ManagedResource;
@@ -224,6 +226,9 @@ public class VertxPlatformHttpServer extends ServiceSupport
implements CamelCont
executor =
context.getExecutorServiceManager().newSingleThreadExecutor(this,
"platform-http-service");
server = vertx.createHttpServer(options);
+ // the result of listen is handled on a Vert.x thread: an exception
thrown there does not reach this thread,
+ // so keep the failure and throw it from here, or the server (and the
CamelContext) starts with nothing listening
+ AtomicReference<Throwable> failure = new AtomicReference<>();
CompletableFuture.runAsync(
() -> {
CountDownLatch latch = new CountDownLatch(1);
@@ -231,16 +236,11 @@ public class VertxPlatformHttpServer extends
ServiceSupport implements CamelCont
.onComplete(result -> {
try {
if (result.failed()) {
- LOGGER.warn("Failed to start Vert.x
HttpServer on {}:{}, reason: {}",
- configuration.getBindHost(),
- configuration.getBindPort(),
- result.cause().getMessage());
-
- throw new
RuntimeException(result.cause());
+ failure.set(result.cause());
+ } else {
+ LOGGER.info("Vert.x HttpServer started
on {}:{}", configuration.getBindHost(),
+ server.actualPort());
}
-
- LOGGER.info("Vert.x HttpServer started on
{}:{}", configuration.getBindHost(),
- server.actualPort());
} finally {
latch.countDown();
}
@@ -254,6 +254,14 @@ public class VertxPlatformHttpServer extends
ServiceSupport implements CamelCont
}
},
executor).toCompletableFuture().join();
+
+ Throwable cause = failure.get();
+ if (cause != null) {
+ throw new RuntimeCamelException(
+ "Failed to start Vert.x HttpServer on " +
configuration.getBindHost() + ":" + configuration.getBindPort()
+ + ", reason: " + cause,
+ cause);
+ }
}
protected void stopServer() {
diff --git
a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerPortInUseTest.java
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerPortInUseTest.java
new file mode 100644
index 000000000000..42d28023f2bf
--- /dev/null
+++
b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpServerPortInUseTest.java
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.platform.http.vertx;
+
+import java.net.BindException;
+import java.net.ServerSocket;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.test.AvailablePortFinder;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class VertxPlatformHttpServerPortInUseTest {
+ @RegisterExtension
+ AvailablePortFinder.Port port = AvailablePortFinder.find();
+
+ @Test
+ void startFailsWhenPortIsInUse() throws Exception {
+ try (ServerSocket portInUse = new ServerSocket(port.getPort());
+ CamelContext context = new DefaultCamelContext()) {
+ VertxPlatformHttpServerConfiguration configuration = new
VertxPlatformHttpServerConfiguration();
+ configuration.setBindPort(port.getPort());
+ VertxPlatformHttpServer server = new
VertxPlatformHttpServer(configuration);
+
+ context.addService(server);
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("platform-http:/test")
+ .setBody().constant("Hello World");
+ }
+ });
+
+ RuntimeCamelException e =
assertThrows(RuntimeCamelException.class, context::start);
+ assertInstanceOf(BindException.class, e.getCause());
+ assertTrue(e.getMessage().contains(":" + port.getPort()),
e.getMessage());
+ assertFalse(context.isStarted());
+
+ // the failed start stopped the server, so it holds neither the
HTTP server nor its own Vert.x instance
+ assertNull(server.getServer());
+ assertNull(server.getVertx());
+ }
+ }
+}
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 0865882254a9..1d16044e4b16 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -3316,6 +3316,15 @@ an `Integer`, `Long`, `Short`, `Float` or `Double` was
written in its binary for
now also written in the charset of the response `Content-Type`, as a `String`
is, rather than in the charset of the
exchange. To send the binary form of a number, convert the body to `byte[]`
first.
+=== camel-platform-http-vertx - the HTTP server fails to start when it cannot
listen on its port
+
+The Vert.x HTTP server of platform-http now fails to start when it cannot
listen on its port, for example because
+another process already uses the port, and so Camel fails to start, with the
bind error as the cause. This also applies
+to the HTTP server and the HTTP management server of camel-platform-http-main
(`camel.server.*` and
+`camel.management.*`), which `camel run` uses: a second `camel run` with the
same `--port` now fails to start. Before,
+the failure was only logged at WARN, and Camel started, with its platform-http
routes reported as started, although
+nothing listened on the port.
+
=== camel-quickfix - an InOut consumer replies only to application messages,
and an InOut producer needs CorrelationCriteria
A consumer with `exchangePattern=InOut` now sends a reply only for an
`AppMessageReceived` event, with the body the