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

fmariani 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 6c2f45894a0d CAMEL-23300: add connectionString option to 
camel-couchbase endpoint
6c2f45894a0d is described below

commit 6c2f45894a0d74ed353a5921111e2d9a37447e4b
Author: Croway <[email protected]>
AuthorDate: Wed Apr 8 16:28:22 2026 +0200

    CAMEL-23300: add connectionString option to camel-couchbase endpoint
    
    The component passed only hostnames to Cluster.connect(), causing the
    SDK to default the KV port to 11210. This made it impossible to connect
    when the KV port is dynamically mapped (e.g., testcontainers with random
    ports). The new connectionString option allows passing a full SDK
    connection string (e.g., couchbase://host:port) that takes precedence
    over hostname extraction.
    
    Also switch test-infra Couchbase container to use random ports by
    default (via isFixedPort) instead of hardcoded fixed ports, and update
    integration tests to pass the connectionString.
---
 .../apache/camel/catalog/components/couchbase.json | 37 +++++++--------
 .../couchbase/CouchbaseEndpointConfigurer.java     |  6 +++
 .../couchbase/CouchbaseEndpointUriFactory.java     |  3 +-
 .../camel/component/couchbase/couchbase.json       | 37 +++++++--------
 .../component/couchbase/CouchbaseEndpoint.java     | 37 ++++++++++-----
 .../couchbase/integration/ConsumeSqlQueryIT.java   |  7 ++-
 .../integration/CouchbaseIntegrationTestBase.java  |  7 ++-
 .../dsl/CouchbaseEndpointBuilderFactory.java       | 54 ++++++++++++++++++++++
 .../CouchbaseLocalContainerInfraService.java       |  9 +---
 9 files changed, 138 insertions(+), 59 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/couchbase.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/couchbase.json
index 09f621e665fd..60ea81ac57d2 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/couchbase.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/couchbase.json
@@ -72,23 +72,24 @@
     "startingIdForInsertsFrom": { "index": 30, "kind": "parameter", 
"displayName": "Starting Id For Inserts From", "group": "producer", "label": 
"producer", "required": false, "type": "integer", "javaType": "long", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Define the starting Id where we are doing an insert operation" },
     "lazyStartProducer": { "index": 31, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
     "additionalHosts": { "index": 32, "kind": "parameter", "displayName": 
"Additional Hosts", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The additional hosts" },
-    "connectTimeout": { "index": 33, "kind": "parameter", "displayName": 
"Connect Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "description": "Define the 
timeoutconnect in milliseconds" },
-    "queryTimeout": { "index": 34, "kind": "parameter", "displayName": "Query 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "2500", "description": "Define the operation 
timeout in milliseconds" },
-    "backoffErrorThreshold": { "index": 35, "kind": "parameter", 
"displayName": "Backoff Error Threshold", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
number of subsequent error polls (failed due some error) that should happen 
before the backoffMultipler should kick-in." },
-    "backoffIdleThreshold": { "index": 36, "kind": "parameter", "displayName": 
"Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "The number of subsequent 
idle polls that should happen before the backoffMultipler should kick-in." },
-    "backoffMultiplier": { "index": 37, "kind": "parameter", "displayName": 
"Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "To let the scheduled 
polling consumer backoff if there has been a number of subsequent idles\/errors 
in a row. The multiplier is then the number of polls that will be skipped 
before the next actual attempt is h [...]
-    "delay": { "index": 38, "kind": "parameter", "displayName": "Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 500, "description": "Milliseconds before the 
next poll." },
-    "greedy": { "index": 39, "kind": "parameter", "displayName": "Greedy", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If greedy is enabled, 
then the ScheduledPollConsumer will run immediately again, if the previous run 
polled 1 or more messages." },
-    "initialDelay": { "index": 40, "kind": "parameter", "displayName": 
"Initial Delay", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": 1000, "description": 
"Milliseconds before the first poll starts." },
-    "repeatCount": { "index": 41, "kind": "parameter", "displayName": "Repeat 
Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 0, "description": "Specifies a maximum limit 
of number of fires. So if you set it to 1, the scheduler will only fire once. 
If you set it to 5, it will only fire five times. A value of zero or negative 
means fire forever." },
-    "runLoggingLevel": { "index": 42, "kind": "parameter", "displayName": "Run 
Logging Level", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", 
"enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "TRACE", 
"description": "The consumer logs a start\/complete log line when it polls. 
This option allows you to configure the log [...]
-    "scheduledExecutorService": { "index": 43, "kind": "parameter", 
"displayName": "Scheduled Executor Service", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "object", "javaType": 
"java.util.concurrent.ScheduledExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows for configuring a 
custom\/shared thread pool to use for the consumer. By default each consumer 
has its own single threaded thread pool." },
-    "scheduler": { "index": 44, "kind": "parameter", "displayName": 
"Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "none", "description": "To 
use a cron scheduler from either camel-spring or camel-quartz component. Use 
value spring or quartz for built in scheduler" },
-    "schedulerProperties": { "index": 45, "kind": "parameter", "displayName": 
"Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", 
"multiValue": true, "deprecated": false, "autowired": false, "secret": false, 
"description": "To configure additional properties when using a custom 
scheduler or any of the Quartz, Spring based scheduler. This i [...]
-    "startScheduler": { "index": 46, "kind": "parameter", "displayName": 
"Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Whether the scheduler should be auto started." },
-    "timeUnit": { "index": 47, "kind": "parameter", "displayName": "Time 
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "enum", "javaType": "java.util.concurrent.TimeUnit", "enum": [ 
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", 
"DAYS" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and 
delay options." },
-    "useFixedDelay": { "index": 48, "kind": "parameter", "displayName": "Use 
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in 
JDK for details." },
-    "password": { "index": 49, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password to use" },
-    "username": { "index": 50, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username to use" }
+    "connectionString": { "index": 33, "kind": "parameter", "displayName": 
"Connection String", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The Couchbase SDK 
connection string to use (e.g., couchbase:\/\/hostname:11210). When set, this 
takes precedence over the hostname and port options for the SDK connection. 
This is useful when the KV port is not  [...]
+    "connectTimeout": { "index": 34, "kind": "parameter", "displayName": 
"Connect Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "description": "Define the 
timeoutconnect in milliseconds" },
+    "queryTimeout": { "index": 35, "kind": "parameter", "displayName": "Query 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "2500", "description": "Define the operation 
timeout in milliseconds" },
+    "backoffErrorThreshold": { "index": 36, "kind": "parameter", 
"displayName": "Backoff Error Threshold", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
number of subsequent error polls (failed due some error) that should happen 
before the backoffMultipler should kick-in." },
+    "backoffIdleThreshold": { "index": 37, "kind": "parameter", "displayName": 
"Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "The number of subsequent 
idle polls that should happen before the backoffMultipler should kick-in." },
+    "backoffMultiplier": { "index": 38, "kind": "parameter", "displayName": 
"Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "To let the scheduled 
polling consumer backoff if there has been a number of subsequent idles\/errors 
in a row. The multiplier is then the number of polls that will be skipped 
before the next actual attempt is h [...]
+    "delay": { "index": 39, "kind": "parameter", "displayName": "Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 500, "description": "Milliseconds before the 
next poll." },
+    "greedy": { "index": 40, "kind": "parameter", "displayName": "Greedy", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If greedy is enabled, 
then the ScheduledPollConsumer will run immediately again, if the previous run 
polled 1 or more messages." },
+    "initialDelay": { "index": 41, "kind": "parameter", "displayName": 
"Initial Delay", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": 1000, "description": 
"Milliseconds before the first poll starts." },
+    "repeatCount": { "index": 42, "kind": "parameter", "displayName": "Repeat 
Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 0, "description": "Specifies a maximum limit 
of number of fires. So if you set it to 1, the scheduler will only fire once. 
If you set it to 5, it will only fire five times. A value of zero or negative 
means fire forever." },
+    "runLoggingLevel": { "index": 43, "kind": "parameter", "displayName": "Run 
Logging Level", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", 
"enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "TRACE", 
"description": "The consumer logs a start\/complete log line when it polls. 
This option allows you to configure the log [...]
+    "scheduledExecutorService": { "index": 44, "kind": "parameter", 
"displayName": "Scheduled Executor Service", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "object", "javaType": 
"java.util.concurrent.ScheduledExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows for configuring a 
custom\/shared thread pool to use for the consumer. By default each consumer 
has its own single threaded thread pool." },
+    "scheduler": { "index": 45, "kind": "parameter", "displayName": 
"Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "none", "description": "To 
use a cron scheduler from either camel-spring or camel-quartz component. Use 
value spring or quartz for built in scheduler" },
+    "schedulerProperties": { "index": 46, "kind": "parameter", "displayName": 
"Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", 
"multiValue": true, "deprecated": false, "autowired": false, "secret": false, 
"description": "To configure additional properties when using a custom 
scheduler or any of the Quartz, Spring based scheduler. This i [...]
+    "startScheduler": { "index": 47, "kind": "parameter", "displayName": 
"Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Whether the scheduler should be auto started." },
+    "timeUnit": { "index": 48, "kind": "parameter", "displayName": "Time 
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "enum", "javaType": "java.util.concurrent.TimeUnit", "enum": [ 
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", 
"DAYS" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and 
delay options." },
+    "useFixedDelay": { "index": 49, "kind": "parameter", "displayName": "Use 
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in 
JDK for details." },
+    "password": { "index": 50, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password to use" },
+    "username": { "index": 51, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username to use" }
   }
 }
diff --git 
a/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointConfigurer.java
 
b/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointConfigurer.java
index 193f721fa385..5e3907065bf1 100644
--- 
a/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointConfigurer.java
+++ 
b/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointConfigurer.java
@@ -39,6 +39,8 @@ public class CouchbaseEndpointConfigurer extends 
PropertyConfigurerSupport imple
         case "collection": target.setCollection(property(camelContext, 
java.lang.String.class, value)); return true;
         case "connecttimeout":
         case "connectTimeout": target.setConnectTimeout(property(camelContext, 
java.time.Duration.class, value).toMillis()); return true;
+        case "connectionstring":
+        case "connectionString": 
target.setConnectionString(property(camelContext, java.lang.String.class, 
value)); return true;
         case "consumerprocessedstrategy":
         case "consumerProcessedStrategy": 
target.setConsumerProcessedStrategy(property(camelContext, 
java.lang.String.class, value)); return true;
         case "consumerretrypause":
@@ -128,6 +130,8 @@ public class CouchbaseEndpointConfigurer extends 
PropertyConfigurerSupport imple
         case "collection": return java.lang.String.class;
         case "connecttimeout":
         case "connectTimeout": return long.class;
+        case "connectionstring":
+        case "connectionString": return java.lang.String.class;
         case "consumerprocessedstrategy":
         case "consumerProcessedStrategy": return java.lang.String.class;
         case "consumerretrypause":
@@ -218,6 +222,8 @@ public class CouchbaseEndpointConfigurer extends 
PropertyConfigurerSupport imple
         case "collection": return target.getCollection();
         case "connecttimeout":
         case "connectTimeout": return target.getConnectTimeout();
+        case "connectionstring":
+        case "connectionString": return target.getConnectionString();
         case "consumerprocessedstrategy":
         case "consumerProcessedStrategy": return 
target.getConsumerProcessedStrategy();
         case "consumerretrypause":
diff --git 
a/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointUriFactory.java
 
b/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointUriFactory.java
index a6fd42ec6e89..93b59012c1b2 100644
--- 
a/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointUriFactory.java
+++ 
b/components/camel-couchbase/src/generated/java/org/apache/camel/component/couchbase/CouchbaseEndpointUriFactory.java
@@ -23,7 +23,7 @@ public class CouchbaseEndpointUriFactory extends 
org.apache.camel.support.compon
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(51);
+        Set<String> props = new HashSet<>(52);
         props.add("additionalHosts");
         props.add("autoStartIdForInserts");
         props.add("backoffErrorThreshold");
@@ -33,6 +33,7 @@ public class CouchbaseEndpointUriFactory extends 
org.apache.camel.support.compon
         props.add("bucket");
         props.add("collection");
         props.add("connectTimeout");
+        props.add("connectionString");
         props.add("consumerProcessedStrategy");
         props.add("consumerRetryPause");
         props.add("delay");
diff --git 
a/components/camel-couchbase/src/generated/resources/META-INF/org/apache/camel/component/couchbase/couchbase.json
 
b/components/camel-couchbase/src/generated/resources/META-INF/org/apache/camel/component/couchbase/couchbase.json
index 09f621e665fd..60ea81ac57d2 100644
--- 
a/components/camel-couchbase/src/generated/resources/META-INF/org/apache/camel/component/couchbase/couchbase.json
+++ 
b/components/camel-couchbase/src/generated/resources/META-INF/org/apache/camel/component/couchbase/couchbase.json
@@ -72,23 +72,24 @@
     "startingIdForInsertsFrom": { "index": 30, "kind": "parameter", 
"displayName": "Starting Id For Inserts From", "group": "producer", "label": 
"producer", "required": false, "type": "integer", "javaType": "long", 
"deprecated": false, "autowired": false, "secret": false, "description": 
"Define the starting Id where we are doing an insert operation" },
     "lazyStartProducer": { "index": 31, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produ [...]
     "additionalHosts": { "index": 32, "kind": "parameter", "displayName": 
"Additional Hosts", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The additional hosts" },
-    "connectTimeout": { "index": 33, "kind": "parameter", "displayName": 
"Connect Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "description": "Define the 
timeoutconnect in milliseconds" },
-    "queryTimeout": { "index": 34, "kind": "parameter", "displayName": "Query 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "2500", "description": "Define the operation 
timeout in milliseconds" },
-    "backoffErrorThreshold": { "index": 35, "kind": "parameter", 
"displayName": "Backoff Error Threshold", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
number of subsequent error polls (failed due some error) that should happen 
before the backoffMultipler should kick-in." },
-    "backoffIdleThreshold": { "index": 36, "kind": "parameter", "displayName": 
"Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "The number of subsequent 
idle polls that should happen before the backoffMultipler should kick-in." },
-    "backoffMultiplier": { "index": 37, "kind": "parameter", "displayName": 
"Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "To let the scheduled 
polling consumer backoff if there has been a number of subsequent idles\/errors 
in a row. The multiplier is then the number of polls that will be skipped 
before the next actual attempt is h [...]
-    "delay": { "index": 38, "kind": "parameter", "displayName": "Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 500, "description": "Milliseconds before the 
next poll." },
-    "greedy": { "index": 39, "kind": "parameter", "displayName": "Greedy", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If greedy is enabled, 
then the ScheduledPollConsumer will run immediately again, if the previous run 
polled 1 or more messages." },
-    "initialDelay": { "index": 40, "kind": "parameter", "displayName": 
"Initial Delay", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": 1000, "description": 
"Milliseconds before the first poll starts." },
-    "repeatCount": { "index": 41, "kind": "parameter", "displayName": "Repeat 
Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 0, "description": "Specifies a maximum limit 
of number of fires. So if you set it to 1, the scheduler will only fire once. 
If you set it to 5, it will only fire five times. A value of zero or negative 
means fire forever." },
-    "runLoggingLevel": { "index": 42, "kind": "parameter", "displayName": "Run 
Logging Level", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", 
"enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "TRACE", 
"description": "The consumer logs a start\/complete log line when it polls. 
This option allows you to configure the log [...]
-    "scheduledExecutorService": { "index": 43, "kind": "parameter", 
"displayName": "Scheduled Executor Service", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "object", "javaType": 
"java.util.concurrent.ScheduledExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows for configuring a 
custom\/shared thread pool to use for the consumer. By default each consumer 
has its own single threaded thread pool." },
-    "scheduler": { "index": 44, "kind": "parameter", "displayName": 
"Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "none", "description": "To 
use a cron scheduler from either camel-spring or camel-quartz component. Use 
value spring or quartz for built in scheduler" },
-    "schedulerProperties": { "index": 45, "kind": "parameter", "displayName": 
"Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", 
"multiValue": true, "deprecated": false, "autowired": false, "secret": false, 
"description": "To configure additional properties when using a custom 
scheduler or any of the Quartz, Spring based scheduler. This i [...]
-    "startScheduler": { "index": 46, "kind": "parameter", "displayName": 
"Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Whether the scheduler should be auto started." },
-    "timeUnit": { "index": 47, "kind": "parameter", "displayName": "Time 
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "enum", "javaType": "java.util.concurrent.TimeUnit", "enum": [ 
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", 
"DAYS" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and 
delay options." },
-    "useFixedDelay": { "index": 48, "kind": "parameter", "displayName": "Use 
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in 
JDK for details." },
-    "password": { "index": 49, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password to use" },
-    "username": { "index": 50, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username to use" }
+    "connectionString": { "index": 33, "kind": "parameter", "displayName": 
"Connection String", "group": "advanced", "label": "advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The Couchbase SDK 
connection string to use (e.g., couchbase:\/\/hostname:11210). When set, this 
takes precedence over the hostname and port options for the SDK connection. 
This is useful when the KV port is not  [...]
+    "connectTimeout": { "index": 34, "kind": "parameter", "displayName": 
"Connect Timeout", "group": "advanced", "label": "advanced", "required": false, 
"type": "duration", "javaType": "long", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "30000", "description": "Define the 
timeoutconnect in milliseconds" },
+    "queryTimeout": { "index": 35, "kind": "parameter", "displayName": "Query 
Timeout", "group": "advanced", "label": "advanced", "required": false, "type": 
"duration", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "2500", "description": "Define the operation 
timeout in milliseconds" },
+    "backoffErrorThreshold": { "index": 36, "kind": "parameter", 
"displayName": "Backoff Error Threshold", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "integer", "javaType": "int", 
"deprecated": false, "autowired": false, "secret": false, "description": "The 
number of subsequent error polls (failed due some error) that should happen 
before the backoffMultipler should kick-in." },
+    "backoffIdleThreshold": { "index": 37, "kind": "parameter", "displayName": 
"Backoff Idle Threshold", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "The number of subsequent 
idle polls that should happen before the backoffMultipler should kick-in." },
+    "backoffMultiplier": { "index": 38, "kind": "parameter", "displayName": 
"Backoff Multiplier", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "int", "deprecated": false, 
"autowired": false, "secret": false, "description": "To let the scheduled 
polling consumer backoff if there has been a number of subsequent idles\/errors 
in a row. The multiplier is then the number of polls that will be skipped 
before the next actual attempt is h [...]
+    "delay": { "index": 39, "kind": "parameter", "displayName": "Delay", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 500, "description": "Milliseconds before the 
next poll." },
+    "greedy": { "index": 40, "kind": "parameter", "displayName": "Greedy", 
"group": "scheduler", "label": "consumer,scheduler", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "If greedy is enabled, 
then the ScheduledPollConsumer will run immediately again, if the previous run 
polled 1 or more messages." },
+    "initialDelay": { "index": 41, "kind": "parameter", "displayName": 
"Initial Delay", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "integer", "javaType": "long", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": 1000, "description": 
"Milliseconds before the first poll starts." },
+    "repeatCount": { "index": 42, "kind": "parameter", "displayName": "Repeat 
Count", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "integer", "javaType": "long", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": 0, "description": "Specifies a maximum limit 
of number of fires. So if you set it to 1, the scheduler will only fire once. 
If you set it to 5, it will only fire five times. A value of zero or negative 
means fire forever." },
+    "runLoggingLevel": { "index": 43, "kind": "parameter", "displayName": "Run 
Logging Level", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "enum", "javaType": "org.apache.camel.LoggingLevel", 
"enum": [ "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "TRACE", 
"description": "The consumer logs a start\/complete log line when it polls. 
This option allows you to configure the log [...]
+    "scheduledExecutorService": { "index": 44, "kind": "parameter", 
"displayName": "Scheduled Executor Service", "group": "scheduler", "label": 
"consumer,scheduler", "required": false, "type": "object", "javaType": 
"java.util.concurrent.ScheduledExecutorService", "deprecated": false, 
"autowired": false, "secret": false, "description": "Allows for configuring a 
custom\/shared thread pool to use for the consumer. By default each consumer 
has its own single threaded thread pool." },
+    "scheduler": { "index": 45, "kind": "parameter", "displayName": 
"Scheduler", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "object", "javaType": "java.lang.Object", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "none", "description": "To 
use a cron scheduler from either camel-spring or camel-quartz component. Use 
value spring or quartz for built in scheduler" },
+    "schedulerProperties": { "index": 46, "kind": "parameter", "displayName": 
"Scheduler Properties", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "object", "javaType": 
"java.util.Map<java.lang.String, java.lang.Object>", "prefix": "scheduler.", 
"multiValue": true, "deprecated": false, "autowired": false, "secret": false, 
"description": "To configure additional properties when using a custom 
scheduler or any of the Quartz, Spring based scheduler. This i [...]
+    "startScheduler": { "index": 47, "kind": "parameter", "displayName": 
"Start Scheduler", "group": "scheduler", "label": "consumer,scheduler", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": true, 
"description": "Whether the scheduler should be auto started." },
+    "timeUnit": { "index": 48, "kind": "parameter", "displayName": "Time 
Unit", "group": "scheduler", "label": "consumer,scheduler", "required": false, 
"type": "enum", "javaType": "java.util.concurrent.TimeUnit", "enum": [ 
"NANOSECONDS", "MICROSECONDS", "MILLISECONDS", "SECONDS", "MINUTES", "HOURS", 
"DAYS" ], "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "MILLISECONDS", "description": "Time unit for initialDelay and 
delay options." },
+    "useFixedDelay": { "index": 49, "kind": "parameter", "displayName": "Use 
Fixed Delay", "group": "scheduler", "label": "consumer,scheduler", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Controls if fixed delay or fixed rate is used. See ScheduledExecutorService in 
JDK for details." },
+    "password": { "index": 50, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password to use" },
+    "username": { "index": 51, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username to use" }
   }
 }
diff --git 
a/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
 
b/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
index 93d7624efb64..4ed312af1ebd 100644
--- 
a/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
+++ 
b/components/camel-couchbase/src/main/java/org/apache/camel/component/couchbase/CouchbaseEndpoint.java
@@ -96,6 +96,10 @@ public class CouchbaseEndpoint extends ScheduledPollEndpoint 
implements Endpoint
     @UriParam(label = "advanced")
     private String additionalHosts;
 
+    // Connection string
+    @UriParam(label = "advanced")
+    private String connectionString;
+
     // Persistence and replication parameters
     @UriParam(label = "producer", defaultValue = "0")
     private int persistTo;
@@ -325,6 +329,19 @@ public class CouchbaseEndpoint extends 
ScheduledPollEndpoint implements Endpoint
         this.additionalHosts = additionalHosts;
     }
 
+    public String getConnectionString() {
+        return connectionString;
+    }
+
+    /**
+     * The Couchbase SDK connection string to use (e.g., 
couchbase://hostname:11210). When set, this takes precedence
+     * over the hostname and port options for the SDK connection. This is 
useful when the KV port is not the default
+     * 11210, for example when connecting to a container with dynamic port 
mappings.
+     */
+    public void setConnectionString(String connectionString) {
+        this.connectionString = connectionString;
+    }
+
     public int getPersistTo() {
         return persistTo;
     }
@@ -653,26 +670,24 @@ public class CouchbaseEndpoint extends 
ScheduledPollEndpoint implements Endpoint
 
     //create from couchbase-client
     private Bucket createClient() throws Exception {
-        List<URI> hosts = Arrays.asList(makeBootstrapURI());
-        String connectionString;
-
         if (bucket == null || bucket.isEmpty()) {
             throw new CamelException(COUCHBASE_URI_ERROR);
         }
 
         ClusterEnvironment env = createClusterEnvironment();
 
-        String addHosts = hosts.stream()
-                .map(URI::getHost)
-                .collect(Collectors.joining(","));
-
-        if (!addHosts.isEmpty()) {
-            connectionString = addHosts;
+        String connStr;
+        if (connectionString != null && !connectionString.isEmpty()) {
+            connStr = connectionString;
         } else {
-            connectionString = hostname;
+            List<URI> hosts = Arrays.asList(makeBootstrapURI());
+            String addHosts = hosts.stream()
+                    .map(URI::getHost)
+                    .collect(Collectors.joining(","));
+            connStr = !addHosts.isEmpty() ? addHosts : hostname;
         }
 
-        Cluster cluster = Cluster.connect(connectionString, ClusterOptions
+        Cluster cluster = Cluster.connect(connStr, ClusterOptions
                 .clusterOptions(username, password)
                 .environment(env));
 
diff --git 
a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
 
b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
index 8da0ae899300..1e7142265e6a 100644
--- 
a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
+++ 
b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/ConsumeSqlQueryIT.java
@@ -140,8 +140,11 @@ public class ConsumeSqlQueryIT extends CamelTestSupport {
     }
 
     public String getConnectionUri() {
-        return 
String.format("couchbase:http://%s:%d?bucket=%s&username=%s&password=%s";, 
service.getHostname(),
-                service.getPort(), bucketName, service.getUsername(), 
service.getPassword());
+        return String.format(
+                
"couchbase:http://%s:%d?bucket=%s&username=%s&password=%s&connectionString=%s";,
+                service.getHostname(),
+                service.getPort(), bucketName, service.getUsername(), 
service.getPassword(),
+                service.getConnectionString());
     }
 
     @Override
diff --git 
a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/CouchbaseIntegrationTestBase.java
 
b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/CouchbaseIntegrationTestBase.java
index d95cea520078..e023a686705c 100644
--- 
a/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/CouchbaseIntegrationTestBase.java
+++ 
b/components/camel-couchbase/src/test/java/org/apache/camel/component/couchbase/integration/CouchbaseIntegrationTestBase.java
@@ -71,8 +71,11 @@ public class CouchbaseIntegrationTestBase extends 
CamelTestSupport {
     }
 
     public String getConnectionUri() {
-        return 
String.format("couchbase:http://%s:%d?bucket=%s&username=%s&password=%s";, 
service.getHostname(),
-                service.getPort(), bucketName, service.getUsername(), 
service.getPassword());
+        return String.format(
+                
"couchbase:http://%s:%d?bucket=%s&username=%s&password=%s&connectionString=%s";,
+                service.getHostname(),
+                service.getPort(), bucketName, service.getUsername(), 
service.getPassword(),
+                service.getConnectionString());
     }
 
 }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CouchbaseEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CouchbaseEndpointBuilderFactory.java
index 21e31040c8c4..6f14804ab3c4 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CouchbaseEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/CouchbaseEndpointBuilderFactory.java
@@ -1079,6 +1079,24 @@ public interface CouchbaseEndpointBuilderFactory {
             doSetProperty("additionalHosts", additionalHosts);
             return this;
         }
+        /**
+         * The Couchbase SDK connection string to use (e.g.,
+         * couchbase://hostname:11210). When set, this takes precedence over 
the
+         * hostname and port options for the SDK connection. This is useful 
when
+         * the KV port is not the default 11210, for example when connecting to
+         * a container with dynamic port mappings.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param connectionString the value to set
+         * @return the dsl builder
+         */
+        default AdvancedCouchbaseEndpointConsumerBuilder 
connectionString(String connectionString) {
+            doSetProperty("connectionString", connectionString);
+            return this;
+        }
         /**
          * Define the timeoutconnect in milliseconds.
          * 
@@ -1501,6 +1519,24 @@ public interface CouchbaseEndpointBuilderFactory {
             doSetProperty("additionalHosts", additionalHosts);
             return this;
         }
+        /**
+         * The Couchbase SDK connection string to use (e.g.,
+         * couchbase://hostname:11210). When set, this takes precedence over 
the
+         * hostname and port options for the SDK connection. This is useful 
when
+         * the KV port is not the default 11210, for example when connecting to
+         * a container with dynamic port mappings.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param connectionString the value to set
+         * @return the dsl builder
+         */
+        default AdvancedCouchbaseEndpointProducerBuilder 
connectionString(String connectionString) {
+            doSetProperty("connectionString", connectionString);
+            return this;
+        }
         /**
          * Define the timeoutconnect in milliseconds.
          * 
@@ -1686,6 +1722,24 @@ public interface CouchbaseEndpointBuilderFactory {
             doSetProperty("additionalHosts", additionalHosts);
             return this;
         }
+        /**
+         * The Couchbase SDK connection string to use (e.g.,
+         * couchbase://hostname:11210). When set, this takes precedence over 
the
+         * hostname and port options for the SDK connection. This is useful 
when
+         * the KV port is not the default 11210, for example when connecting to
+         * a container with dynamic port mappings.
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param connectionString the value to set
+         * @return the dsl builder
+         */
+        default AdvancedCouchbaseEndpointBuilder connectionString(String 
connectionString) {
+            doSetProperty("connectionString", connectionString);
+            return this;
+        }
         /**
          * Define the timeoutconnect in milliseconds.
          * 
diff --git 
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
 
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
index 9178b3b954b5..62347ef1422e 100644
--- 
a/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
+++ 
b/test-infra/camel-test-infra-couchbase/src/main/java/org/apache/camel/test/infra/couchbase/services/CouchbaseLocalContainerInfraService.java
@@ -40,22 +40,17 @@ import org.testcontainers.utility.DockerImageName;
               serviceAlias = { "couchbase" })
 public class CouchbaseLocalContainerInfraService implements 
CouchbaseInfraService, ContainerService<CouchbaseContainer> {
 
-    /*
-     * Couchbase container uses a dynamic port for the KV service. The 
configuration
-     * used in the Camel component tries to use that port by default, and it 
seems
-     * we cannot configure it. Therefore, we override the default container and
-     * force the default KV port to be used.
-     */
     private class CustomCouchbaseContainer extends CouchbaseContainer {
         public CustomCouchbaseContainer(String imageName) {
             
super(DockerImageName.parse(imageName).asCompatibleSubstituteFor("couchbase/server"));
 
+            boolean fixedPort = 
ContainerEnvironmentUtil.isFixedPort(CouchbaseLocalContainerInfraService.class);
             final int kvPort = 11210;
             final int managementPort = 8091;
             final int viewPort = 8092;
             final int queryPort = 8093;
             final int searchPort = 8094;
-            ContainerEnvironmentUtil.configurePorts(this, true,
+            ContainerEnvironmentUtil.configurePorts(this, fixedPort,
                     ContainerEnvironmentUtil.PortConfig.primary(kvPort),
                     
ContainerEnvironmentUtil.PortConfig.secondary(managementPort),
                     ContainerEnvironmentUtil.PortConfig.secondary(viewPort),

Reply via email to