You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2023/01/17 13:38:28 UTC

[camel] branch camel-3.x updated: CAMEL-17895: Add option for vertx-websocket consumer to connect as a WS client

This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch camel-3.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-3.x by this push:
     new 7bd2f0fa047 CAMEL-17895: Add option for vertx-websocket consumer to connect as a WS client
7bd2f0fa047 is described below

commit 7bd2f0fa0476f46cb4f4e7556f32466accd30322
Author: James Netherton <ja...@gmail.com>
AuthorDate: Tue Jan 17 10:28:39 2023 +0000

    CAMEL-17895: Add option for vertx-websocket consumer to connect as a WS client
---
 .../camel/catalog/components/vertx-websocket.json  |  10 +-
 .../VertxWebsocketEndpointConfigurer.java          |  24 +++
 .../VertxWebsocketEndpointUriFactory.java          |  16 +-
 .../component/vertx/websocket/vertx-websocket.json |  10 +-
 .../src/main/docs/vertx-websocket-component.adoc   |   8 +
 .../websocket/VertxWebsocketClientConsumer.java    | 107 +++++++++++++
 .../vertx/websocket/VertxWebsocketComponent.java   |  52 ++++--
 .../websocket/VertxWebsocketConfiguration.java     |  92 +++++++----
 .../vertx/websocket/VertxWebsocketConsumer.java    |   4 -
 .../vertx/websocket/VertxWebsocketEndpoint.java    |  69 ++++++--
 .../vertx/websocket/VertxWebsocketHelper.java      |  55 +------
 .../vertx/websocket/VertxWebsocketHost.java        |  10 +-
 ...WebsocketConsumerAsClientBinaryMessageTest.java |  56 +++++++
 ...ertxWebsocketConsumerAsClientReconnectTest.java | 124 +++++++++++++++
 ...txWebsocketConsumerAsClientTextMessageTest.java |  54 +++++++
 .../vertx/websocket/VertxWebsocketHelperTest.java  |  54 -------
 .../vertx/websocket/VertxWebsocketSSLTest.java     |  71 +++++++++
 .../vertx/websocket/VertxWebsocketTest.java        |  12 +-
 .../src/generated/resources/metadata.json          |   2 +-
 .../builder/endpoint/StaticEndpointBuilders.java   |  32 +---
 .../dsl/VertxWebsocketEndpointBuilderFactory.java  | 175 +++++++++++++++++----
 21 files changed, 793 insertions(+), 244 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-websocket.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-websocket.json
index 9de30f57d75..70e2ec1891d 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-websocket.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-websocket.json
@@ -19,7 +19,7 @@
     "api": false,
     "consumerOnly": false,
     "producerOnly": false,
-    "lenientProperties": false
+    "lenientProperties": true
   },
   "componentProperties": {
     "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
@@ -36,10 +36,12 @@
     "CamelVertxWebsocket.remoteAddress": { "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "io.vertx.core.net.SocketAddress", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The remote address.", "constantName": "org.apache.camel.component.vertx.websocket.VertxWebsocketConstants#REMOTE_ADDRESS" }
   },
   "properties": {
-    "host": { "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "0.0.0.0", "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The host that the consumer should bind to or the host of the remote websocket destination that the pro [...]
-    "port": { "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The port that the consumer should bind to or port of the remote websocket destination that the producer should connect to" },
-    "path": { "kind": "path", "displayName": "Path", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "\/", "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The path that the consumer should bind to or path of the remote websocket destination [...]
+    "websocketURI": { "kind": "path", "displayName": "Websocket URI", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The WebSocket URI address to use." },
     "allowedOriginPattern": { "kind": "parameter", "displayName": "Allowed Origin Pattern", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "Regex pattern to match the origin header sent by WebSocket clients" },
+    "consumeAsClient": { "kind": "parameter", "displayName": "Consume As Client", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When set to true, the consumer acts as a WebSocket client, creating exchang [...]
+    "maxReconnectAttempts": { "kind": "parameter", "displayName": "Max Reconnect Attempts", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When consumeAsClient is set to true this sets the maximum number of allow [...]
+    "reconnectInitialDelay": { "kind": "parameter", "displayName": "Reconnect Initial Delay", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When consumeAsClient is set to true this sets the initial delay in mill [...]
+    "reconnectInterval": { "kind": "parameter", "displayName": "Reconnect Interval", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When consumeAsClient is set to true this sets the interval in milliseconds at [...]
     "router": { "kind": "parameter", "displayName": "Router", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "io.vertx.ext.web.Router", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "To use an existing vertx router for the HTTP server" },
     "serverOptions": { "kind": "parameter", "displayName": "Server Options", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "io.vertx.core.http.HttpServerOptions", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "Sets customized options for configuring the HTTP server hosting the WebSock [...]
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now [...]
diff --git a/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointConfigurer.java b/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointConfigurer.java
index 5f495b3f1a8..171b587c15f 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointConfigurer.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointConfigurer.java
@@ -29,12 +29,20 @@ public class VertxWebsocketEndpointConfigurer extends PropertyConfigurerSupport
         case "clientOptions": target.getConfiguration().setClientOptions(property(camelContext, io.vertx.core.http.HttpClientOptions.class, value)); return true;
         case "clientsubprotocols":
         case "clientSubProtocols": target.getConfiguration().setClientSubProtocols(property(camelContext, java.lang.String.class, value)); return true;
+        case "consumeasclient":
+        case "consumeAsClient": target.getConfiguration().setConsumeAsClient(property(camelContext, boolean.class, value)); return true;
         case "exceptionhandler":
         case "exceptionHandler": target.setExceptionHandler(property(camelContext, org.apache.camel.spi.ExceptionHandler.class, value)); return true;
         case "exchangepattern":
         case "exchangePattern": target.setExchangePattern(property(camelContext, org.apache.camel.ExchangePattern.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
+        case "maxreconnectattempts":
+        case "maxReconnectAttempts": target.getConfiguration().setMaxReconnectAttempts(property(camelContext, int.class, value)); return true;
+        case "reconnectinitialdelay":
+        case "reconnectInitialDelay": target.getConfiguration().setReconnectInitialDelay(property(camelContext, int.class, value)); return true;
+        case "reconnectinterval":
+        case "reconnectInterval": target.getConfiguration().setReconnectInterval(property(camelContext, int.class, value)); return true;
         case "router": target.getConfiguration().setRouter(property(camelContext, io.vertx.ext.web.Router.class, value)); return true;
         case "sendtoall":
         case "sendToAll": target.getConfiguration().setSendToAll(property(camelContext, boolean.class, value)); return true;
@@ -57,12 +65,20 @@ public class VertxWebsocketEndpointConfigurer extends PropertyConfigurerSupport
         case "clientOptions": return io.vertx.core.http.HttpClientOptions.class;
         case "clientsubprotocols":
         case "clientSubProtocols": return java.lang.String.class;
+        case "consumeasclient":
+        case "consumeAsClient": return boolean.class;
         case "exceptionhandler":
         case "exceptionHandler": return org.apache.camel.spi.ExceptionHandler.class;
         case "exchangepattern":
         case "exchangePattern": return org.apache.camel.ExchangePattern.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
+        case "maxreconnectattempts":
+        case "maxReconnectAttempts": return int.class;
+        case "reconnectinitialdelay":
+        case "reconnectInitialDelay": return int.class;
+        case "reconnectinterval":
+        case "reconnectInterval": return int.class;
         case "router": return io.vertx.ext.web.Router.class;
         case "sendtoall":
         case "sendToAll": return boolean.class;
@@ -86,12 +102,20 @@ public class VertxWebsocketEndpointConfigurer extends PropertyConfigurerSupport
         case "clientOptions": return target.getConfiguration().getClientOptions();
         case "clientsubprotocols":
         case "clientSubProtocols": return target.getConfiguration().getClientSubProtocols();
+        case "consumeasclient":
+        case "consumeAsClient": return target.getConfiguration().isConsumeAsClient();
         case "exceptionhandler":
         case "exceptionHandler": return target.getExceptionHandler();
         case "exchangepattern":
         case "exchangePattern": return target.getExchangePattern();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
+        case "maxreconnectattempts":
+        case "maxReconnectAttempts": return target.getConfiguration().getMaxReconnectAttempts();
+        case "reconnectinitialdelay":
+        case "reconnectInitialDelay": return target.getConfiguration().getReconnectInitialDelay();
+        case "reconnectinterval":
+        case "reconnectInterval": return target.getConfiguration().getReconnectInterval();
         case "router": return target.getConfiguration().getRouter();
         case "sendtoall":
         case "sendToAll": return target.getConfiguration().isSendToAll();
diff --git a/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointUriFactory.java b/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointUriFactory.java
index 18632f37b09..11bc9610b1d 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointUriFactory.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/generated/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpointUriFactory.java
@@ -21,21 +21,23 @@ public class VertxWebsocketEndpointUriFactory extends org.apache.camel.support.c
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(14);
+        Set<String> props = new HashSet<>(16);
         props.add("allowedOriginPattern");
         props.add("bridgeErrorHandler");
         props.add("clientOptions");
         props.add("clientSubProtocols");
+        props.add("consumeAsClient");
         props.add("exceptionHandler");
         props.add("exchangePattern");
-        props.add("host");
         props.add("lazyStartProducer");
-        props.add("path");
-        props.add("port");
+        props.add("maxReconnectAttempts");
+        props.add("reconnectInitialDelay");
+        props.add("reconnectInterval");
         props.add("router");
         props.add("sendToAll");
         props.add("serverOptions");
         props.add("sslContextParameters");
+        props.add("websocketURI");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
         SECRET_PROPERTY_NAMES = Collections.emptySet();
         MULTI_VALUE_PREFIXES = Collections.emptySet();
@@ -53,9 +55,7 @@ public class VertxWebsocketEndpointUriFactory extends org.apache.camel.support.c
 
         Map<String, Object> copy = new HashMap<>(properties);
 
-        uri = buildPathParameter(syntax, uri, "host", "0.0.0.0", false, copy);
-        uri = buildPathParameter(syntax, uri, "port", 0, false, copy);
-        uri = buildPathParameter(syntax, uri, "path", "/", true, copy);
+        uri = buildPathParameter(syntax, uri, "websocketURI", null, true, copy);
         uri = buildQueryParameters(uri, copy, encode);
         return uri;
     }
@@ -77,7 +77,7 @@ public class VertxWebsocketEndpointUriFactory extends org.apache.camel.support.c
 
     @Override
     public boolean isLenientProperties() {
-        return false;
+        return true;
     }
 }
 
diff --git a/components/camel-vertx/camel-vertx-websocket/src/generated/resources/org/apache/camel/component/vertx/websocket/vertx-websocket.json b/components/camel-vertx/camel-vertx-websocket/src/generated/resources/org/apache/camel/component/vertx/websocket/vertx-websocket.json
index 9de30f57d75..70e2ec1891d 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/generated/resources/org/apache/camel/component/vertx/websocket/vertx-websocket.json
+++ b/components/camel-vertx/camel-vertx-websocket/src/generated/resources/org/apache/camel/component/vertx/websocket/vertx-websocket.json
@@ -19,7 +19,7 @@
     "api": false,
     "consumerOnly": false,
     "producerOnly": false,
-    "lenientProperties": false
+    "lenientProperties": true
   },
   "componentProperties": {
     "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a me [...]
@@ -36,10 +36,12 @@
     "CamelVertxWebsocket.remoteAddress": { "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "io.vertx.core.net.SocketAddress", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The remote address.", "constantName": "org.apache.camel.component.vertx.websocket.VertxWebsocketConstants#REMOTE_ADDRESS" }
   },
   "properties": {
-    "host": { "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "0.0.0.0", "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The host that the consumer should bind to or the host of the remote websocket destination that the pro [...]
-    "port": { "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The port that the consumer should bind to or port of the remote websocket destination that the producer should connect to" },
-    "path": { "kind": "path", "displayName": "Path", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "\/", "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The path that the consumer should bind to or path of the remote websocket destination [...]
+    "websocketURI": { "kind": "path", "displayName": "Websocket URI", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "The WebSocket URI address to use." },
     "allowedOriginPattern": { "kind": "parameter", "displayName": "Allowed Origin Pattern", "group": "consumer", "label": "consumer", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "Regex pattern to match the origin header sent by WebSocket clients" },
+    "consumeAsClient": { "kind": "parameter", "displayName": "Consume As Client", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When set to true, the consumer acts as a WebSocket client, creating exchang [...]
+    "maxReconnectAttempts": { "kind": "parameter", "displayName": "Max Reconnect Attempts", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When consumeAsClient is set to true this sets the maximum number of allow [...]
+    "reconnectInitialDelay": { "kind": "parameter", "displayName": "Reconnect Initial Delay", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When consumeAsClient is set to true this sets the initial delay in mill [...]
+    "reconnectInterval": { "kind": "parameter", "displayName": "Reconnect Interval", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "When consumeAsClient is set to true this sets the interval in milliseconds at [...]
     "router": { "kind": "parameter", "displayName": "Router", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "io.vertx.ext.web.Router", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "To use an existing vertx router for the HTTP server" },
     "serverOptions": { "kind": "parameter", "displayName": "Server Options", "group": "consumer", "label": "consumer", "required": false, "type": "object", "javaType": "io.vertx.core.http.HttpServerOptions", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.websocket.VertxWebsocketConfiguration", "configurationField": "configuration", "description": "Sets customized options for configuring the HTTP server hosting the WebSock [...]
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now [...]
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/docs/vertx-websocket-component.adoc b/components/camel-vertx/camel-vertx-websocket/src/main/docs/vertx-websocket-component.adoc
index 4044eefb293..e97ffb771fb 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/docs/vertx-websocket-component.adoc
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/docs/vertx-websocket-component.adoc
@@ -63,6 +63,14 @@ from("vertx-websocket:localhost:8080/echo")
     .to("vertx-websocket:localhost:8080/echo");
 ----
 
+It's also possible to configure the consumer to connect as a WebSocket client on a remote address with the `consumeAsClient` option:
+
+[source,java]
+----
+from("vertx-websocket:my.websocket.com:8080/chat?consumeAsClient=true")
+    .log("Got WebSocket message ${body}");
+----
+
 == SSL
 
 By default, the `ws://` protocol is used, but secure connections with `wss://` are supported by configuring the consumer or producer
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketClientConsumer.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketClientConsumer.java
new file mode 100644
index 00000000000..d00e5bd67c2
--- /dev/null
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketClientConsumer.java
@@ -0,0 +1,107 @@
+/*
+ * 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.vertx.websocket;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.http.WebSocket;
+import io.vertx.core.net.impl.ConnectionBase;
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.support.DefaultConsumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VertxWebsocketClientConsumer extends DefaultConsumer {
+    private static final Logger LOG = LoggerFactory.getLogger(VertxWebsocketClientConsumer.class);
+
+    public VertxWebsocketClientConsumer(Endpoint endpoint, Processor processor) {
+        super(endpoint, processor);
+    }
+
+    @Override
+    public VertxWebsocketEndpoint getEndpoint() {
+        return (VertxWebsocketEndpoint) super.getEndpoint();
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        configureWebSocketHandlers(getEndpoint().getWebSocket());
+    }
+
+    protected void configureWebSocketHandlers(WebSocket webSocket) {
+        webSocket.binaryMessageHandler(buffer -> this.handleResult(buffer.getBytes()));
+        webSocket.textMessageHandler(this::handleResult);
+        webSocket.closeHandler(event -> {
+            if (isStarted()) {
+                LOG.info("WebSocket disconnected from {}. Attempting to reconnect...", webSocket.remoteAddress());
+                VertxWebsocketConfiguration configuration = getEndpoint().getConfiguration();
+                AtomicInteger reconnectAttempts = new AtomicInteger();
+
+                Vertx vertx = getEndpoint().getVertx();
+                vertx.setPeriodic(configuration.getReconnectInitialDelay(), configuration.getReconnectInterval(), timerId -> {
+                    vertx.executeBlocking(promise -> {
+                        try {
+                            configureWebSocketHandlers(getEndpoint().getWebSocket());
+                            vertx.cancelTimer(timerId);
+                            promise.complete();
+                        } catch (Exception e) {
+                            promise.fail(e);
+                        }
+                    }, false, result -> {
+                        if (result.failed()) {
+                            Throwable cause = result.cause();
+                            if (cause != null) {
+                                LOG.debug("WebSocket reconnect to {} failed due to {}", webSocket.remoteAddress(), cause);
+                            }
+
+                            if (configuration.getMaxReconnectAttempts() > 0) {
+                                if (reconnectAttempts.incrementAndGet() == configuration.getMaxReconnectAttempts()) {
+                                    LOG.warn("Reconnect max attempts ({}) exhausted. Giving up trying to reconnect to {}",
+                                            configuration.getMaxReconnectAttempts(), webSocket.remoteAddress());
+                                    vertx.cancelTimer(timerId);
+                                }
+                            }
+                        }
+                    });
+                });
+            }
+        });
+        webSocket.exceptionHandler(exception -> {
+            Throwable cause = exception.getCause();
+            if (cause == ConnectionBase.CLOSED_EXCEPTION) {
+                // Ignore as there's already a close handler registered
+                return;
+            }
+            Exchange exchange = createExchange(false);
+            getExceptionHandler().handleException("Error processing exchange", exchange, cause);
+            releaseExchange(exchange, false);
+        });
+    }
+
+    protected void handleResult(Object result) {
+        Exchange exchange = createExchange(true);
+        AsyncCallback cb = defaultConsumerCallback(exchange, true);
+        Message message = exchange.getMessage();
+        message.setBody(result);
+        getAsyncProcessor().process(exchange, cb);
+    }
+}
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketComponent.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketComponent.java
index a25e8199ad9..c7dad0cb573 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketComponent.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketComponent.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.vertx.websocket;
 
+import java.net.URI;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -28,11 +29,10 @@ import org.apache.camel.SSLContextParametersAware;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.util.URISupport;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
 
 import static org.apache.camel.component.vertx.websocket.VertxWebsocketHelper.createHostKey;
-import static org.apache.camel.component.vertx.websocket.VertxWebsocketHelper.extractHostName;
-import static org.apache.camel.component.vertx.websocket.VertxWebsocketHelper.extractPath;
-import static org.apache.camel.component.vertx.websocket.VertxWebsocketHelper.extractPortNumber;
 
 @Component("vertx-websocket")
 public class VertxWebsocketComponent extends DefaultComponent implements SSLContextParametersAware {
@@ -51,10 +51,44 @@ public class VertxWebsocketComponent extends DefaultComponent implements SSLCont
 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        String wsUri = remaining;
+        if (wsUri.matches("^wss?:.*")) {
+            int schemeSeparatorIndex = remaining.indexOf(":");
+            String scheme = remaining.substring(0, schemeSeparatorIndex);
+            wsUri = scheme + "://" + wsUri.replaceFirst("wss?:/*", "");
+        } else {
+            String scheme = "ws://";
+            // Preserves backwards compatibility for the vertx-websocket  on camel-quarkus / camel-k where the HTTP
+            // server is provided by the runtime platform and the host:port configuration is not strictly required
+            if (remaining.startsWith("/")) {
+                wsUri = scheme + "/" + remaining.replaceAll("^/+", "");
+            } else {
+                wsUri = scheme + remaining;
+            }
+        }
+
+        URI endpointUri = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(wsUri));
+        URI websocketURI = URISupport.createRemainingURI(endpointUri, parameters);
+
+        if (websocketURI.getHost() == null || websocketURI.getPort() == -1) {
+            String host = websocketURI.getHost();
+            int port = websocketURI.getPort();
+            if (websocketURI.getHost() == null) {
+                host = VertxWebsocketConstants.DEFAULT_VERTX_SERVER_HOST;
+            }
+
+            if (websocketURI.getPort() == -1) {
+                port = VertxWebsocketConstants.DEFAULT_VERTX_SERVER_PORT;
+            }
+
+            websocketURI = new URI(
+                    websocketURI.getScheme(), websocketURI.getUserInfo(),
+                    host, port, websocketURI.getPath(), websocketURI.getQuery(),
+                    websocketURI.getFragment());
+        }
+
         VertxWebsocketConfiguration configuration = new VertxWebsocketConfiguration();
-        configuration.setHost(extractHostName(remaining));
-        configuration.setPort(extractPortNumber(remaining));
-        configuration.setPath(extractPath(remaining));
+        configuration.setWebsocketURI(websocketURI);
 
         VertxWebsocketEndpoint endpoint = new VertxWebsocketEndpoint(uri, this, configuration);
         setProperties(endpoint, parameters);
@@ -103,7 +137,7 @@ public class VertxWebsocketComponent extends DefaultComponent implements SSLCont
     public void connectConsumer(VertxWebsocketConsumer consumer) {
         VertxWebsocketEndpoint endpoint = consumer.getEndpoint();
         VertxWebsocketConfiguration configuration = endpoint.getConfiguration();
-        VertxWebsocketHostKey hostKey = createHostKey(configuration);
+        VertxWebsocketHostKey hostKey = createHostKey(configuration.getWebsocketURI());
         VertxWebsocketHost host = vertxHostRegistry.computeIfAbsent(hostKey, key -> {
             Router vertxRouter = configuration.getRouter();
             if (vertxRouter == null) {
@@ -141,11 +175,11 @@ public class VertxWebsocketComponent extends DefaultComponent implements SSLCont
     public void disconnectConsumer(VertxWebsocketConsumer consumer) {
         VertxWebsocketEndpoint endpoint = consumer.getEndpoint();
         VertxWebsocketConfiguration configuration = endpoint.getConfiguration();
-        VertxWebsocketHostKey hostKey = createHostKey(configuration);
+        VertxWebsocketHostKey hostKey = createHostKey(configuration.getWebsocketURI());
         VertxWebsocketHost vertxWebsocketHost = vertxHostRegistry.remove(hostKey);
 
         if (vertxWebsocketHost != null) {
-            vertxWebsocketHost.disconnect(configuration.getPath());
+            vertxWebsocketHost.disconnect(configuration.getWebsocketURI().getPath());
         }
     }
 
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConfiguration.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConfiguration.java
index 0906c3ed6d8..9f4ea89fae8 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConfiguration.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConfiguration.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.vertx.websocket;
 
+import java.net.URI;
+
 import io.vertx.core.http.HttpClientOptions;
 import io.vertx.core.http.HttpServerOptions;
 import io.vertx.ext.web.Router;
@@ -28,19 +30,23 @@ import org.apache.camel.support.jsse.SSLContextParameters;
 @UriParams
 public class VertxWebsocketConfiguration {
 
-    @UriPath(name = "host", defaultValue = VertxWebsocketConstants.DEFAULT_VERTX_SERVER_HOST)
-    private String host;
-    @UriPath(name = "port", defaultValue = "0")
-    private int port;
-    @UriPath(name = "path", defaultValue = VertxWebsocketConstants.DEFAULT_VERTX_SERVER_PATH)
+    @UriPath
     @Metadata(required = true)
-    private String path;
+    private URI websocketURI;
     @UriParam(label = "consumer")
     private String allowedOriginPattern;
     @UriParam(label = "consumer")
     private Router router;
     @UriParam(label = "consumer")
     private HttpServerOptions serverOptions;
+    @UriParam(label = "consumer")
+    private boolean consumeAsClient;
+    @UriParam(label = "consumer", defaultValue = "0")
+    private int reconnectInitialDelay;
+    @UriParam(label = "consumer", defaultValue = "1000")
+    private int reconnectInterval = 1000;
+    @UriParam(label = "consumer", defaultValue = "0")
+    private int maxReconnectAttempts;
     @UriParam(label = "producer")
     private HttpClientOptions clientOptions;
     @UriParam(label = "producer")
@@ -50,32 +56,15 @@ public class VertxWebsocketConfiguration {
     @UriParam(label = "security")
     private SSLContextParameters sslContextParameters;
 
-    public String getHost() {
-        return host;
-    }
-
     /**
-     * The host that the consumer should bind to or the host of the remote websocket destination that the producer
-     * should connect to
+     * The WebSocket URI address to use.
      */
-    public void setHost(String host) {
-        this.host = host;
+    public void setWebsocketURI(URI websocketURI) {
+        this.websocketURI = websocketURI;
     }
 
-    public int getPort() {
-        return port;
-    }
-
-    /**
-     * The port that the consumer should bind to or port of the remote websocket destination that the producer should
-     * connect to
-     */
-    public void setPort(int port) {
-        this.port = port;
-    }
-
-    public String getPath() {
-        return path;
+    public URI getWebsocketURI() {
+        return websocketURI;
     }
 
     /**
@@ -96,12 +85,51 @@ public class VertxWebsocketConfiguration {
         this.serverOptions = serverOptions;
     }
 
+    public boolean isConsumeAsClient() {
+        return consumeAsClient;
+    }
+
+    public int getReconnectInitialDelay() {
+        return reconnectInitialDelay;
+    }
+
+    /**
+     * When consumeAsClient is set to true this sets the initial delay in milliseconds before attempting to reconnect to
+     * a previously closed WebSocket.
+     */
+    public void setReconnectInitialDelay(int reconnectInitialDelay) {
+        this.reconnectInitialDelay = reconnectInitialDelay;
+    }
+
+    public int getReconnectInterval() {
+        return reconnectInterval;
+    }
+
+    /**
+     * When consumeAsClient is set to true this sets the interval in milliseconds at which reconnecting to a previously
+     * closed WebSocket occurs.
+     */
+    public void setReconnectInterval(int reconnectInterval) {
+        this.reconnectInterval = reconnectInterval;
+    }
+
+    public int getMaxReconnectAttempts() {
+        return maxReconnectAttempts;
+    }
+
+    /**
+     * When consumeAsClient is set to true this sets the maximum number of allowed reconnection attempts to a previously
+     * closed WebSocket. A value of 0 (the default) will attempt to reconnect indefinitely.
+     */
+    public void setMaxReconnectAttempts(int maxReconnectAttempts) {
+        this.maxReconnectAttempts = maxReconnectAttempts;
+    }
+
     /**
-     * The path that the consumer should bind to or path of the remote websocket destination that the producer should
-     * connect to
+     * When set to true, the consumer acts as a WebSocket client, creating exchanges on each received WebSocket event.
      */
-    public void setPath(String path) {
-        this.path = path;
+    public void setConsumeAsClient(boolean consumeAsClient) {
+        this.consumeAsClient = consumeAsClient;
     }
 
     public HttpClientOptions getClientOptions() {
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumer.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumer.java
index cf1991dfdf0..86933866748 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumer.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumer.java
@@ -22,16 +22,12 @@ import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.support.DefaultConsumer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Implements a Vert.x Handler to handle WebSocket upgrade
  */
 public class VertxWebsocketConsumer extends DefaultConsumer {
 
-    private static final Logger LOG = LoggerFactory.getLogger(VertxWebsocketConsumer.class);
-
     private final VertxWebsocketEndpoint endpoint;
 
     public VertxWebsocketConsumer(VertxWebsocketEndpoint endpoint, Processor processor) {
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java
index 750c81dbf1d..473192fad52 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketEndpoint.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.vertx.websocket;
 
+import java.net.URI;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
@@ -39,12 +40,13 @@ import org.apache.camel.spi.UriParam;
 import org.apache.camel.support.DefaultEndpoint;
 import org.apache.camel.support.jsse.SSLContextParameters;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @UriEndpoint(firstVersion = "3.5.0", scheme = "vertx-websocket", title = "Vert.x WebSocket",
              syntax = "vertx-websocket:host:port/path", category = { Category.WEBSOCKET },
-             headersClass = VertxWebsocketConstants.class)
+             headersClass = VertxWebsocketConstants.class, lenientProperties = true)
 public class VertxWebsocketEndpoint extends DefaultEndpoint {
 
     private static final Logger LOG = LoggerFactory.getLogger(VertxWebsocketEndpoint.class);
@@ -52,6 +54,7 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
     @UriParam
     private VertxWebsocketConfiguration configuration;
 
+    private HttpClient client;
     private WebSocket webSocket;
 
     public VertxWebsocketEndpoint(String uri, VertxWebsocketComponent component, VertxWebsocketConfiguration configuration) {
@@ -59,6 +62,12 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
         this.configuration = configuration;
     }
 
+    @Override
+    public boolean isLenientProperties() {
+        // Enable custom query parameters to be passed on the producer WebSocket URI
+        return true;
+    }
+
     @Override
     public VertxWebsocketComponent getComponent() {
         return (VertxWebsocketComponent) super.getComponent();
@@ -71,7 +80,12 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
 
     @Override
     public Consumer createConsumer(Processor processor) throws Exception {
-        VertxWebsocketConsumer consumer = new VertxWebsocketConsumer(this, processor);
+        Consumer consumer;
+        if (getConfiguration().isConsumeAsClient()) {
+            consumer = new VertxWebsocketClientConsumer(this, processor);
+        } else {
+            consumer = new VertxWebsocketConsumer(this, processor);
+        }
         configureConsumer(consumer);
         return consumer;
     }
@@ -82,6 +96,12 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
             webSocket.close();
             webSocket = null;
         }
+
+        if (client != null) {
+            client.close();
+            client = null;
+        }
+
         super.doStop();
     }
 
@@ -93,11 +113,9 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
         return getComponent().getVertx();
     }
 
-    protected WebSocket getWebSocket(Exchange exchange) throws Exception {
-        if (webSocket == null || webSocket.isClosed()) {
+    protected WebSocket getWebSocket() throws Exception {
+        if (client == null) {
             HttpClientOptions options = configuration.getClientOptions();
-            HttpClient client;
-
             if (options == null) {
                 options = new HttpClientOptions();
             }
@@ -108,12 +126,28 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
             }
 
             client = getVertx().createHttpClient(options);
+        }
+
+        if (webSocket == null || webSocket.isClosed()) {
+            HttpClientOptions options = configuration.getClientOptions();
 
+            if (options == null) {
+                options = new HttpClientOptions();
+            }
+
+            SSLContextParameters sslContextParameters = configuration.getSslContextParameters();
+            if (sslContextParameters != null) {
+                VertxHelper.setupSSLOptions(getCamelContext(), sslContextParameters, options);
+            }
+
+            URI websocketURI = configuration.getWebsocketURI();
             WebSocketConnectOptions connectOptions = new WebSocketConnectOptions();
-            connectOptions.setHost(configuration.getHost());
-            connectOptions.setPort(configuration.getPort());
-            connectOptions.setURI(configuration.getPath());
-            connectOptions.setSsl(options.isSsl());
+            connectOptions.setHost(websocketURI.getHost());
+            connectOptions.setURI(URISupport.pathAndQueryOf(websocketURI));
+            connectOptions.setSsl(options.isSsl() || websocketURI.getScheme().length() == 3);
+            if (websocketURI.getPort() > 0) {
+                connectOptions.setPort(websocketURI.getPort());
+            }
 
             String subProtocols = configuration.getClientSubProtocols();
             if (ObjectHelper.isNotEmpty(subProtocols)) {
@@ -123,7 +157,7 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
             CompletableFuture<WebSocket> future = new CompletableFuture<>();
             client.webSocket(connectOptions, result -> {
                 if (!result.failed()) {
-                    LOG.info("Connected to WebSocket on {}:{}", configuration.getHost(), configuration.getPort());
+                    LOG.info("Connected to WebSocket on {}", result.result().remoteAddress());
                     future.complete(result.result());
                 } else {
                     webSocket = null;
@@ -131,11 +165,14 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
                 }
             });
             webSocket = future.get(options.getConnectTimeout(), TimeUnit.MILLISECONDS);
-            webSocket.exceptionHandler(event -> exchange.setException(event.getCause()));
         }
         return webSocket;
     }
 
+    protected WebSocket getWebSocket(Exchange exchange) throws Exception {
+        return getWebSocket().exceptionHandler(event -> exchange.setException(event.getCause()));
+    }
+
     protected Map<VertxWebsocketHostKey, VertxWebsocketHost> getVertxHostRegistry() {
         return getComponent().getVertxHostRegistry();
     }
@@ -147,7 +184,7 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
         Map<VertxWebsocketHostKey, VertxWebsocketHost> registry = getVertxHostRegistry();
         for (VertxWebsocketHost host : registry.values()) {
             Map<String, ServerWebSocket> hostPeers = host.getConnectedPeers();
-            if (hostPeers.containsKey(connectionKey) && host.getPort() == getConfiguration().getPort()) {
+            if (hostPeers.containsKey(connectionKey) && host.getPort() == getConfiguration().getWebsocketURI().getPort()) {
                 return hostPeers.get(connectionKey);
             }
         }
@@ -161,15 +198,15 @@ public class VertxWebsocketEndpoint extends DefaultEndpoint {
         return getVertxHostRegistry()
                 .values()
                 .stream()
-                .filter(host -> host.getPort() == getConfiguration().getPort())
+                .filter(host -> host.getPort() == getConfiguration().getWebsocketURI().getPort())
                 .flatMap(host -> host.getConnectedPeers().entrySet().stream())
-                .filter(entry -> entry.getValue().path().equals(getConfiguration().getPath()))
+                .filter(entry -> entry.getValue().path().equals(getConfiguration().getWebsocketURI().getPath()))
                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
     }
 
     protected boolean isManagedPort() {
         return getVertxHostRegistry().values()
                 .stream()
-                .anyMatch(host -> host.getPort() == getConfiguration().getPort());
+                .anyMatch(host -> host.getPort() == getConfiguration().getWebsocketURI().getPort());
     }
 }
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelper.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelper.java
index 41f727e385f..81743bd5e60 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelper.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelper.java
@@ -16,65 +16,18 @@
  */
 package org.apache.camel.component.vertx.websocket;
 
+import java.net.URI;
+
 public final class VertxWebsocketHelper {
 
     private VertxWebsocketHelper() {
         // Utility class
     }
 
-    /**
-     * Extracts the port number from the endpoint URI path or returns the Vert.x default HTTP server port (0) if one was
-     * not provided
-     */
-    public static int extractPortNumber(String remaining) {
-        int index1 = remaining.indexOf(':');
-        int index2 = remaining.indexOf('/');
-        if (index1 != -1 && index2 != -1) {
-            String result = remaining.substring(index1 + 1, index2);
-            if (result.isEmpty()) {
-                throw new IllegalArgumentException("Unable to resolve port from URI: " + remaining);
-            }
-
-            try {
-                return Integer.parseInt(result);
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException("Unable to parse port: " + result);
-            }
-        } else {
-            return VertxWebsocketConstants.DEFAULT_VERTX_SERVER_PORT;
-        }
-    }
-
-    /**
-     * Extracts the host name from the endpoint URI path or returns the Vert.x default HTTP server host (0.0.0.0) if one
-     * was not provided
-     */
-    public static String extractHostName(String remaining) {
-        int index = remaining.indexOf(':');
-        if (index != -1) {
-            return remaining.substring(0, index);
-        } else {
-            return VertxWebsocketConstants.DEFAULT_VERTX_SERVER_HOST;
-        }
-    }
-
-    /**
-     * Extracts the WebSocket path from the endpoint URI path or returns the Vert.x default HTTP server path (/) if one
-     * was not provided
-     */
-    public static String extractPath(String remaining) {
-        int index = remaining.indexOf('/');
-        if (index != -1) {
-            return remaining.substring(index);
-        } else {
-            return VertxWebsocketConstants.DEFAULT_VERTX_SERVER_PATH + remaining;
-        }
-    }
-
     /**
      * Creates a VertxWebsocketHostKey from a given VertxWebsocketConfiguration
      */
-    public static VertxWebsocketHostKey createHostKey(VertxWebsocketConfiguration configuration) {
-        return new VertxWebsocketHostKey(configuration.getHost(), configuration.getPort());
+    public static VertxWebsocketHostKey createHostKey(URI websockerURI) {
+        return new VertxWebsocketHostKey(websockerURI.getHost(), websockerURI.getPort());
     }
 }
diff --git a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHost.java b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHost.java
index 16dc26339b6..3da512133f6 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHost.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/main/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHost.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.vertx.websocket;
 
+import java.net.URI;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
@@ -68,12 +69,13 @@ public class VertxWebsocketHost {
         VertxWebsocketEndpoint endpoint = consumer.getEndpoint();
         VertxWebsocketConfiguration configuration = endpoint.getConfiguration();
 
-        LOG.info("Connected consumer for path {}", configuration.getPath());
+        URI websocketURI = configuration.getWebsocketURI();
+        LOG.info("Connected consumer for path {}", websocketURI.getPath());
         Router router = hostConfiguration.getRouter();
-        Route route = router.route(configuration.getPath());
+        Route route = router.route(websocketURI.getPath());
 
         if (!ObjectHelper.isEmpty(configuration.getAllowedOriginPattern())) {
-            CorsHandler corsHandler = CorsHandler.create(configuration.getAllowedOriginPattern());
+            CorsHandler corsHandler = CorsHandler.create().addRelativeOrigin(configuration.getAllowedOriginPattern());
             route.handler(corsHandler);
         }
 
@@ -132,7 +134,7 @@ public class VertxWebsocketHost {
             }
         });
 
-        routeRegistry.put(configuration.getPath(), route);
+        routeRegistry.put(websocketURI.getPath(), route);
     }
 
     /**
diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientBinaryMessageTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientBinaryMessageTest.java
new file mode 100644
index 00000000000..8f60b912f25
--- /dev/null
+++ b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientBinaryMessageTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.vertx.websocket;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+
+public class VertxWebsocketConsumerAsClientBinaryMessageTest extends VertxWebSocketTestSupport {
+
+    @Test
+    void testConsumeAsClientBinaryMessage() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.expectedMessageCount(5);
+
+        String uri = String.format("vertx-websocket:localhost:%d/echo", port);
+        for (int i = 1; i <= 5; i++) {
+            template.sendBody(uri, "Hello World".getBytes(StandardCharsets.UTF_8));
+        }
+
+        mockEndpoint.assertIsSatisfied();
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                fromF("vertx-websocket:localhost:%d/echo", port)
+                        .log("Server consumer received message: ${body}")
+                        .toF("vertx-websocket:localhost:%d/echo?sendToAll=true", port);
+
+                fromF("vertx-websocket:localhost:%d/echo?consumeAsClient=true", port)
+                        .log("Client consumer received message: ${body}")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientReconnectTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientReconnectTest.java
new file mode 100644
index 00000000000..81e7d56a218
--- /dev/null
+++ b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientReconnectTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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.vertx.websocket;
+
+import java.net.ConnectException;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class VertxWebsocketConsumerAsClientReconnectTest extends VertxWebSocketTestSupport {
+    @Test
+    void testReconnect() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.expectedBodiesReceived("Hello World");
+
+        String uri = String.format("vertx-websocket:localhost:%d/echo", port);
+        template.sendBody(uri, "Hello World");
+        mockEndpoint.assertIsSatisfied();
+
+        // Stop server
+        mockEndpoint.reset();
+        mockEndpoint.expectedBodiesReceived("Hello World Again");
+
+        context.getRouteController().stopRoute("server");
+
+        // Verify that we cannot send messages
+        Exchange exchange = template.send(uri, new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getMessage().setBody("Hello World Again");
+            }
+        });
+        Exception exception = exchange.getException();
+        Assertions.assertNotNull(exception);
+        Assertions.assertInstanceOf(ConnectException.class, exception.getCause());
+
+        // Restart server
+        context.getRouteController().startRoute("server");
+
+        // Wait for client consumer reconnect
+        Thread.sleep(300);
+
+        // Verify that the client consumer reconnected
+        template.sendBody(uri, "Hello World Again");
+        mockEndpoint.assertIsSatisfied();
+    }
+
+    @Test
+    void testMaxReconnect() throws Exception {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result2");
+        mockEndpoint.expectedBodiesReceived("Hello World");
+
+        String uri = String.format("vertx-websocket:localhost:%d/echo", port);
+        template.sendBody(uri, "Hello World");
+        mockEndpoint.assertIsSatisfied();
+
+        // Stop server
+        mockEndpoint.reset();
+        mockEndpoint.expectedMessageCount(0);
+
+        context.getRouteController().stopRoute("server");
+
+        // Verify that we cannot send messages
+        Exchange exchange = template.send(uri, new Processor() {
+            @Override
+            public void process(Exchange exchange) throws Exception {
+                exchange.getMessage().setBody("Hello World Again");
+            }
+        });
+        Exception exception = exchange.getException();
+        Assertions.assertNotNull(exception);
+        Assertions.assertInstanceOf(ConnectException.class, exception.getCause());
+
+        // Wait for client consumer reconnect max attempts to be exhausted
+        Thread.sleep(300);
+
+        // Restart server
+        context.getRouteController().startRoute("server");
+
+        // Verify that the client consumer gave up reconnecting
+        template.sendBody(uri, "Hello World Again");
+        mockEndpoint.assertIsSatisfied();
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                fromF("vertx-websocket:localhost:%d/echo", port).routeId("server")
+                        .log("Server consumer: Received message: ${body}")
+                        .toF("vertx-websocket:localhost:%d/echo?sendToAll=true", port);
+
+                fromF("vertx-websocket:localhost:%d/echo?consumeAsClient=true&reconnectInterval=10", port)
+                        .log("Client consumer 1: Received message: ${body}")
+                        .to("mock:result");
+
+                fromF("vertx-websocket:localhost:%d/echo?consumeAsClient=true&reconnectInterval=10&maxReconnectAttempts=1",
+                        port)
+                                .log("Client consumer 2: Received message: ${body}")
+                                .to("mock:result2");
+            }
+        };
+    }
+}
diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientTextMessageTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientTextMessageTest.java
new file mode 100644
index 00000000000..4ecefadeeb1
--- /dev/null
+++ b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketConsumerAsClientTextMessageTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.vertx.websocket;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+
+public class VertxWebsocketConsumerAsClientTextMessageTest extends VertxWebSocketTestSupport {
+
+    @Test
+    void testConsumeAsClientTextMessage() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.expectedMessageCount(5);
+
+        String uri = String.format("vertx-websocket:localhost:%d/echo", port);
+        for (int i = 1; i <= 5; i++) {
+            template.sendBody(uri, "Hello World " + i);
+        }
+
+        mockEndpoint.assertIsSatisfied();
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                fromF("vertx-websocket:localhost:%d/echo", port)
+                        .log("Server consumer received message: ${body}")
+                        .toF("vertx-websocket:localhost:%d/echo?sendToAll=true", port);
+
+                fromF("vertx-websocket:localhost:%d/echo?consumeAsClient=true", port)
+                        .log("Client consumer received message: ${body}")
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelperTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelperTest.java
deleted file mode 100644
index bb217e37eb8..00000000000
--- a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketHelperTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.vertx.websocket;
-
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-public class VertxWebsocketHelperTest {
-
-    @Test
-    public void extractHostNameTest() {
-        assertEquals("test.host.com", VertxWebsocketHelper.extractHostName("test.host.com:8080/path"));
-        assertEquals("0.0.0.0", VertxWebsocketHelper.extractHostName("/path"));
-    }
-
-    @Test
-    public void extractPortTest() {
-        assertEquals(8888, VertxWebsocketHelper.extractPortNumber("test.host.com:8888/path"));
-        assertEquals(0, VertxWebsocketHelper.extractPortNumber("0.0.0.0/path"));
-    }
-
-    @Test
-    public void extractPortInvalidTest() {
-        assertThrows(IllegalArgumentException.class, () -> {
-            VertxWebsocketHelper.extractPortNumber("test.host.com:/path");
-        });
-
-        assertThrows(IllegalArgumentException.class, () -> {
-            VertxWebsocketHelper.extractPortNumber("test.host.com:port/path");
-        });
-    }
-
-    @Test
-    public void extractPathTest() {
-        assertEquals("/web/socket/path", VertxWebsocketHelper.extractPath("test.host.com:8080/web/socket/path"));
-        assertEquals("/", VertxWebsocketHelper.extractPath(""));
-    }
-}
diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketSSLTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketSSLTest.java
index 35813fc4b67..96715f34e1f 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketSSLTest.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketSSLTest.java
@@ -137,6 +137,77 @@ public class VertxWebsocketSSLTest extends VertxWebSocketTestSupport {
         }
     }
 
+    @Test
+    void testWssSchemeUriPrefix() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                fromF("vertx-websocket:localhost:%d/test?sslContextParameters=#serverSSLParameters", port)
+                        .setBody(simple("Hello ${body}"))
+                        .to("mock:result");
+            }
+        });
+
+        context.getRegistry().bind("clientSSLParameters", clientSSLParameters);
+        context.getRegistry().bind("serverSSLParameters", serverSSLParameters);
+
+        context.start();
+        try {
+            MockEndpoint mockEndpoint = context.getEndpoint("mock:result", MockEndpoint.class);
+            mockEndpoint.expectedBodiesReceived("Hello World 1", "Hello World 2", "Hello World 3");
+
+            ProducerTemplate template = context.createProducerTemplate();
+            template.sendBody("vertx-websocket:wss:localhost:" + port + "/test?sslContextParameters=#clientSSLParameters",
+                    "World 1");
+            template.sendBody("vertx-websocket:wss:/localhost:" + port + "/test?sslContextParameters=#clientSSLParameters",
+                    "World 2");
+            template.sendBody("vertx-websocket:wss://localhost:" + port + "/test?sslContextParameters=#clientSSLParameters",
+                    "World 3");
+
+            mockEndpoint.assertIsSatisfied();
+        } finally {
+            context.stop();
+        }
+    }
+
+    @Test
+    void testConsumeAsSecureClient() throws Exception {
+        CamelContext context = new DefaultCamelContext();
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() {
+                fromF("vertx-websocket:localhost:%d/echo?sslContextParameters=#serverSSLParameters", port)
+                        .log("Server consumer received message: ${body}")
+                        .toF("vertx-websocket:localhost:%d/echo?sendToAll=true&sslContextParameters=#clientSSLParameters",
+                                port);
+
+                fromF("vertx-websocket:localhost:%d/echo?consumeAsClient=true&sslContextParameters=#clientSSLParameters", port)
+                        .log("Client consumer received message: ${body}")
+                        .to("mock:result");
+            }
+        });
+
+        context.getRegistry().bind("clientSSLParameters", clientSSLParameters);
+        context.getRegistry().bind("serverSSLParameters", serverSSLParameters);
+
+        context.start();
+        try {
+            MockEndpoint mockEndpoint = context.getEndpoint("mock:result", MockEndpoint.class);
+            mockEndpoint.expectedMessageCount(5);
+
+            ProducerTemplate template = context.createProducerTemplate();
+            String uri = "vertx-websocket:wss:localhost:" + port + "/echo?sslContextParameters=#clientSSLParameters";
+            for (int i = 1; i <= 5; i++) {
+                template.sendBody(uri, "Hello World " + i);
+            }
+
+            mockEndpoint.assertIsSatisfied();
+        } finally {
+            context.stop();
+        }
+    }
+
     @Override
     protected void startCamelContext() {
     }
diff --git a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketTest.java b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketTest.java
index 07692527a3e..07ff5052e9a 100644
--- a/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketTest.java
+++ b/components/camel-vertx/camel-vertx-websocket/src/test/java/org/apache/camel/component/vertx/websocket/VertxWebsocketTest.java
@@ -267,6 +267,16 @@ public class VertxWebsocketTest extends VertxWebSocketTestSupport {
         assertEquals("Hello Camel", results.get(0));
     }
 
+    @Test
+    void testWsSchemeUriPrefix() throws InterruptedException {
+        MockEndpoint mockEndpoint = getMockEndpoint("mock:result");
+        mockEndpoint.expectedBodiesReceived("Hello World 1", "Hello World 2", "Hello World 3");
+        template.sendBody("vertx-websocket:ws:localhost:" + port + "/test", "World 1");
+        template.sendBody("vertx-websocket:ws:/localhost:" + port + "/test", "World 2");
+        template.sendBody("vertx-websocket:ws://localhost:" + port + "/test", "World 3");
+        mockEndpoint.assertIsSatisfied(5000);
+    }
+
     @Override
     protected RoutesBuilder createRouteBuilder() {
         return new RouteBuilder() {
@@ -282,7 +292,7 @@ public class VertxWebsocketTest extends VertxWebSocketTestSupport {
                 fromF("vertx-websocket:localhost:%d/test-other", port)
                         .setBody(simple("Hello ${body}"));
 
-                from("vertx-websocket://greeting")
+                fromF("vertx-websocket:localhost:0/greeting")
                         .setBody(simple("Hello ${body}"))
                         .process(new Processor() {
                             @Override
diff --git a/dsl/camel-componentdsl/src/generated/resources/metadata.json b/dsl/camel-componentdsl/src/generated/resources/metadata.json
index 9a265ffd33f..9de97a215a3 100644
--- a/dsl/camel-componentdsl/src/generated/resources/metadata.json
+++ b/dsl/camel-componentdsl/src/generated/resources/metadata.json
@@ -7293,7 +7293,7 @@
     "api": false,
     "consumerOnly": false,
     "producerOnly": false,
-    "lenientProperties": false
+    "lenientProperties": true
   },
   "VmComponentBuilderFactory": {
     "kind": "component",
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
index b10478d4791..1cd40499852 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/StaticEndpointBuilders.java
@@ -15289,20 +15289,8 @@ public class StaticEndpointBuilders {
      * 
      * Syntax: <code>vertx-websocket:host:port/path</code>
      * 
-     * Path parameter: host
-     * The host that the consumer should bind to or the host of the remote
-     * websocket destination that the producer should connect to
-     * Default value: 0.0.0.0
-     * 
-     * Path parameter: port
-     * The port that the consumer should bind to or port of the remote websocket
-     * destination that the producer should connect to
-     * Default value: 0
-     * 
-     * Path parameter: path (required)
-     * The path that the consumer should bind to or path of the remote websocket
-     * destination that the producer should connect to
-     * Default value: /
+     * Path parameter: websocketURI (required)
+     * The WebSocket URI address to use.
      * 
      * @param path host:port/path
      * @return the dsl builder
@@ -15322,20 +15310,8 @@ public class StaticEndpointBuilders {
      * 
      * Syntax: <code>vertx-websocket:host:port/path</code>
      * 
-     * Path parameter: host
-     * The host that the consumer should bind to or the host of the remote
-     * websocket destination that the producer should connect to
-     * Default value: 0.0.0.0
-     * 
-     * Path parameter: port
-     * The port that the consumer should bind to or port of the remote websocket
-     * destination that the producer should connect to
-     * Default value: 0
-     * 
-     * Path parameter: path (required)
-     * The path that the consumer should bind to or path of the remote websocket
-     * destination that the producer should connect to
-     * Default value: /
+     * Path parameter: websocketURI (required)
+     * The WebSocket URI address to use.
      * 
      * @param componentName to use a custom component name for the endpoint
      * instead of the default name
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/VertxWebsocketEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/VertxWebsocketEndpointBuilderFactory.java
index a51f553cf65..6763c547a69 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/VertxWebsocketEndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/VertxWebsocketEndpointBuilderFactory.java
@@ -59,6 +59,149 @@ public interface VertxWebsocketEndpointBuilderFactory {
             doSetProperty("allowedOriginPattern", allowedOriginPattern);
             return this;
         }
+        /**
+         * When set to true, the consumer acts as a WebSocket client, creating
+         * exchanges on each received WebSocket event.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param consumeAsClient the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder consumeAsClient(
+                boolean consumeAsClient) {
+            doSetProperty("consumeAsClient", consumeAsClient);
+            return this;
+        }
+        /**
+         * When set to true, the consumer acts as a WebSocket client, creating
+         * exchanges on each received WebSocket event.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param consumeAsClient the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder consumeAsClient(
+                String consumeAsClient) {
+            doSetProperty("consumeAsClient", consumeAsClient);
+            return this;
+        }
+        /**
+         * When consumeAsClient is set to true this sets the maximum number of
+         * allowed reconnection attempts to a previously closed WebSocket. A
+         * value of 0 (the default) will attempt to reconnect indefinitely.
+         * 
+         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 0
+         * Group: consumer
+         * 
+         * @param maxReconnectAttempts the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder maxReconnectAttempts(
+                int maxReconnectAttempts) {
+            doSetProperty("maxReconnectAttempts", maxReconnectAttempts);
+            return this;
+        }
+        /**
+         * When consumeAsClient is set to true this sets the maximum number of
+         * allowed reconnection attempts to a previously closed WebSocket. A
+         * value of 0 (the default) will attempt to reconnect indefinitely.
+         * 
+         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 0
+         * Group: consumer
+         * 
+         * @param maxReconnectAttempts the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder maxReconnectAttempts(
+                String maxReconnectAttempts) {
+            doSetProperty("maxReconnectAttempts", maxReconnectAttempts);
+            return this;
+        }
+        /**
+         * When consumeAsClient is set to true this sets the initial delay in
+         * milliseconds before attempting to reconnect to a previously closed
+         * WebSocket.
+         * 
+         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 0
+         * Group: consumer
+         * 
+         * @param reconnectInitialDelay the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder reconnectInitialDelay(
+                int reconnectInitialDelay) {
+            doSetProperty("reconnectInitialDelay", reconnectInitialDelay);
+            return this;
+        }
+        /**
+         * When consumeAsClient is set to true this sets the initial delay in
+         * milliseconds before attempting to reconnect to a previously closed
+         * WebSocket.
+         * 
+         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 0
+         * Group: consumer
+         * 
+         * @param reconnectInitialDelay the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder reconnectInitialDelay(
+                String reconnectInitialDelay) {
+            doSetProperty("reconnectInitialDelay", reconnectInitialDelay);
+            return this;
+        }
+        /**
+         * When consumeAsClient is set to true this sets the interval in
+         * milliseconds at which reconnecting to a previously closed WebSocket
+         * occurs.
+         * 
+         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 1000
+         * Group: consumer
+         * 
+         * @param reconnectInterval the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder reconnectInterval(
+                int reconnectInterval) {
+            doSetProperty("reconnectInterval", reconnectInterval);
+            return this;
+        }
+        /**
+         * When consumeAsClient is set to true this sets the interval in
+         * milliseconds at which reconnecting to a previously closed WebSocket
+         * occurs.
+         * 
+         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 1000
+         * Group: consumer
+         * 
+         * @param reconnectInterval the value to set
+         * @return the dsl builder
+         */
+        default VertxWebsocketEndpointConsumerBuilder reconnectInterval(
+                String reconnectInterval) {
+            doSetProperty("reconnectInterval", reconnectInterval);
+            return this;
+        }
         /**
          * To use an existing vertx router for the HTTP server.
          * 
@@ -557,20 +700,8 @@ public interface VertxWebsocketEndpointBuilderFactory {
          * 
          * Syntax: <code>vertx-websocket:host:port/path</code>
          * 
-         * Path parameter: host
-         * The host that the consumer should bind to or the host of the remote
-         * websocket destination that the producer should connect to
-         * Default value: 0.0.0.0
-         * 
-         * Path parameter: port
-         * The port that the consumer should bind to or port of the remote
-         * websocket destination that the producer should connect to
-         * Default value: 0
-         * 
-         * Path parameter: path (required)
-         * The path that the consumer should bind to or path of the remote
-         * websocket destination that the producer should connect to
-         * Default value: /
+         * Path parameter: websocketURI (required)
+         * The WebSocket URI address to use.
          * 
          * @param path host:port/path
          * @return the dsl builder
@@ -589,20 +720,8 @@ public interface VertxWebsocketEndpointBuilderFactory {
          * 
          * Syntax: <code>vertx-websocket:host:port/path</code>
          * 
-         * Path parameter: host
-         * The host that the consumer should bind to or the host of the remote
-         * websocket destination that the producer should connect to
-         * Default value: 0.0.0.0
-         * 
-         * Path parameter: port
-         * The port that the consumer should bind to or port of the remote
-         * websocket destination that the producer should connect to
-         * Default value: 0
-         * 
-         * Path parameter: path (required)
-         * The path that the consumer should bind to or path of the remote
-         * websocket destination that the producer should connect to
-         * Default value: /
+         * Path parameter: websocketURI (required)
+         * The WebSocket URI address to use.
          * 
          * @param componentName to use a custom component name for the endpoint
          * instead of the default name