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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 58f5ca75401f CAMEL-23812: camel-milo better username & password 
handling (#24193)
58f5ca75401f is described below

commit 58f5ca75401f97e738c24853b8f02e8f940a2a84
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Jun 23 10:32:54 2026 +0200

    CAMEL-23812: camel-milo better username & password handling (#24193)
    
    * feat: add support for explicit username and password handling in Milo 
client
    
    * feat: enhance documentation for explicit username and password handling 
in Milo client
    
    * feat: update password parameter to use 'security'
    
    * chore: regenerate metadata and fix formatting for camel-milo
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
    
    * chore: regenerate catalog, endpointdsl, and componentdsl for camel-milo
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
    
    ---------
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-authored-by: Robin Mattes <[email protected]>
    Co-authored-by: Claude <[email protected]>
---
 .../camel/catalog/components/milo-browse.json      |  8 +-
 .../camel/catalog/components/milo-client.json      |  8 +-
 .../milo/browse/MiloBrowseComponentConfigurer.java |  6 ++
 .../milo/browse/MiloBrowseEndpointConfigurer.java  |  6 ++
 .../milo/browse/MiloBrowseEndpointUriFactory.java  |  7 +-
 .../milo/client/MiloClientComponentConfigurer.java |  6 ++
 .../milo/client/MiloClientEndpointConfigurer.java  |  6 ++
 .../milo/client/MiloClientEndpointUriFactory.java  |  7 +-
 .../camel/component/milo/browse/milo-browse.json   |  8 +-
 .../camel/component/milo/client/milo-client.json   |  8 +-
 .../src/main/docs/milo-client-component.adoc       | 14 ++++
 .../milo/client/MiloClientConfiguration.java       | 32 ++++++++
 .../component/milo/client/MiloClientEndpoint.java  | 20 +++++
 .../milo/client/internal/SubscriptionManager.java  | 24 ++++--
 .../component/milo/AbstractMiloServerTest.java     | 16 +++-
 .../component/milo/ExplicitCredentialsTest.java    | 84 +++++++++++++++++++
 .../dsl/MiloBrowseComponentBuilderFactory.java     | 36 ++++++++
 .../dsl/MiloClientComponentBuilderFactory.java     | 36 ++++++++
 .../dsl/MiloBrowseEndpointBuilderFactory.java      | 32 ++++++++
 .../dsl/MiloClientEndpointBuilderFactory.java      | 96 ++++++++++++++++++++++
 20 files changed, 438 insertions(+), 22 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
index e7391bdcfd0a..aa643bd4b294 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-browse.json
@@ -48,7 +48,9 @@
     "requestedPublishingInterval": { "index": 21, "kind": "property", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in mi [...]
     "requestTimeout": { "index": 22, "kind": "property", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 23, "kind": "property", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 24, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 24, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 25, "kind": "property", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in the [...]
+    "username": { "index": 26, "kind": "property", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when th [...]
   },
   "headers": {
     "CamelMiloNodeIds": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"List", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ids.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_IDS" }
@@ -84,6 +86,8 @@
     "requestedPublishingInterval": { "index": 27, "kind": "parameter", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in m [...]
     "requestTimeout": { "index": 28, "kind": "parameter", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 29, "kind": "parameter", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 30, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 30, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 31, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in th [...]
+    "username": { "index": 32, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when t [...]
   }
 }
diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
index 73e3dabb3dd9..9b90876beadb 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/milo-client.json
@@ -49,7 +49,9 @@
     "requestedPublishingInterval": { "index": 22, "kind": "property", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in mi [...]
     "requestTimeout": { "index": 23, "kind": "property", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 24, "kind": "property", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 25, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 25, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 26, "kind": "property", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in the [...]
+    "username": { "index": 27, "kind": "property", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when th [...]
   },
   "headers": {
     "CamelMiloNodeIds": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"List", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ids.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_IDS" },
@@ -90,6 +92,8 @@
     "requestedPublishingInterval": { "index": 31, "kind": "parameter", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in m [...]
     "requestTimeout": { "index": 32, "kind": "parameter", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 33, "kind": "parameter", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 34, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 34, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 35, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in th [...]
+    "username": { "index": 36, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when t [...]
   }
 }
diff --git 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseComponentConfigurer.java
 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseComponentConfigurer.java
index 6354a32100ef..b7046b96293b 100644
--- 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseComponentConfigurer.java
+++ 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseComponentConfigurer.java
@@ -69,6 +69,7 @@ public class MiloBrowseComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "overrideHost": 
getOrCreateConfiguration(target).setOverrideHost(property(camelContext, 
boolean.class, value)); return true;
         case "overrideport":
         case "overridePort": 
getOrCreateConfiguration(target).setOverridePort(property(camelContext, 
boolean.class, value)); return true;
+        case "password": 
getOrCreateConfiguration(target).setPassword(property(camelContext, 
java.lang.String.class, value)); return true;
         case "producturi":
         case "productUri": 
getOrCreateConfiguration(target).setProductUri(property(camelContext, 
java.lang.String.class, value)); return true;
         case "requesttimeout":
@@ -79,6 +80,7 @@ public class MiloBrowseComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "sessionName": 
getOrCreateConfiguration(target).setSessionName(property(camelContext, 
java.lang.String.class, value)); return true;
         case "sessiontimeout":
         case "sessionTimeout": 
getOrCreateConfiguration(target).setSessionTimeout(property(camelContext, 
java.lang.Long.class, value)); return true;
+        case "username": 
getOrCreateConfiguration(target).setUsername(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
     }
@@ -130,6 +132,7 @@ public class MiloBrowseComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "overrideHost": return boolean.class;
         case "overrideport":
         case "overridePort": return boolean.class;
+        case "password": return java.lang.String.class;
         case "producturi":
         case "productUri": return java.lang.String.class;
         case "requesttimeout":
@@ -140,6 +143,7 @@ public class MiloBrowseComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "sessionName": return java.lang.String.class;
         case "sessiontimeout":
         case "sessionTimeout": return java.lang.Long.class;
+        case "username": return java.lang.String.class;
         default: return null;
         }
     }
@@ -187,6 +191,7 @@ public class MiloBrowseComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "overrideHost": return 
getOrCreateConfiguration(target).isOverrideHost();
         case "overrideport":
         case "overridePort": return 
getOrCreateConfiguration(target).isOverridePort();
+        case "password": return getOrCreateConfiguration(target).getPassword();
         case "producturi":
         case "productUri": return 
getOrCreateConfiguration(target).getProductUri();
         case "requesttimeout":
@@ -197,6 +202,7 @@ public class MiloBrowseComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "sessionName": return 
getOrCreateConfiguration(target).getSessionName();
         case "sessiontimeout":
         case "sessionTimeout": return 
getOrCreateConfiguration(target).getSessionTimeout();
+        case "username": return getOrCreateConfiguration(target).getUsername();
         default: return null;
         }
     }
diff --git 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointConfigurer.java
 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointConfigurer.java
index 708c394aee22..aa088f47c678 100644
--- 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointConfigurer.java
+++ 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointConfigurer.java
@@ -67,6 +67,7 @@ public class MiloBrowseEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "overrideHost": 
target.getConfiguration().setOverrideHost(property(camelContext, boolean.class, 
value)); return true;
         case "overrideport":
         case "overridePort": 
target.getConfiguration().setOverridePort(property(camelContext, boolean.class, 
value)); return true;
+        case "password": 
target.getConfiguration().setPassword(property(camelContext, 
java.lang.String.class, value)); return true;
         case "producturi":
         case "productUri": 
target.getConfiguration().setProductUri(property(camelContext, 
java.lang.String.class, value)); return true;
         case "recursive": target.setRecursive(property(camelContext, 
boolean.class, value)); return true;
@@ -78,6 +79,7 @@ public class MiloBrowseEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "sessionName": 
target.getConfiguration().setSessionName(property(camelContext, 
java.lang.String.class, value)); return true;
         case "sessiontimeout":
         case "sessionTimeout": 
target.getConfiguration().setSessionTimeout(property(camelContext, 
java.lang.Long.class, value)); return true;
+        case "username": 
target.getConfiguration().setUsername(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
     }
@@ -129,6 +131,7 @@ public class MiloBrowseEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "overrideHost": return boolean.class;
         case "overrideport":
         case "overridePort": return boolean.class;
+        case "password": return java.lang.String.class;
         case "producturi":
         case "productUri": return java.lang.String.class;
         case "recursive": return boolean.class;
@@ -140,6 +143,7 @@ public class MiloBrowseEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "sessionName": return java.lang.String.class;
         case "sessiontimeout":
         case "sessionTimeout": return java.lang.Long.class;
+        case "username": return java.lang.String.class;
         default: return null;
         }
     }
@@ -192,6 +196,7 @@ public class MiloBrowseEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "overrideHost": return target.getConfiguration().isOverrideHost();
         case "overrideport":
         case "overridePort": return target.getConfiguration().isOverridePort();
+        case "password": return target.getConfiguration().getPassword();
         case "producturi":
         case "productUri": return target.getConfiguration().getProductUri();
         case "recursive": return target.isRecursive();
@@ -203,6 +208,7 @@ public class MiloBrowseEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "sessionName": return target.getConfiguration().getSessionName();
         case "sessiontimeout":
         case "sessionTimeout": return 
target.getConfiguration().getSessionTimeout();
+        case "username": return target.getConfiguration().getUsername();
         default: return null;
         }
     }
diff --git 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointUriFactory.java
 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointUriFactory.java
index 885128ccdad6..5c7240ca1682 100644
--- 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointUriFactory.java
+++ 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/browse/MiloBrowseEndpointUriFactory.java
@@ -24,7 +24,7 @@ public class MiloBrowseEndpointUriFactory extends 
org.apache.camel.support.compo
     private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(31);
+        Set<String> props = new HashSet<>(33);
         props.add("allowedSecurityPolicies");
         props.add("applicationName");
         props.add("applicationUri");
@@ -50,16 +50,19 @@ public class MiloBrowseEndpointUriFactory extends 
org.apache.camel.support.compo
         props.add("nodeClasses");
         props.add("overrideHost");
         props.add("overridePort");
+        props.add("password");
         props.add("productUri");
         props.add("recursive");
         props.add("requestTimeout");
         props.add("requestedPublishingInterval");
         props.add("sessionName");
         props.add("sessionTimeout");
+        props.add("username");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
-        Set<String> secretProps = new HashSet<>(2);
+        Set<String> secretProps = new HashSet<>(3);
         secretProps.add("keyPassword");
         secretProps.add("keyStorePassword");
+        secretProps.add("password");
         SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
         ENDPOINT_IDENTITY_PROPERTY_NAMES = Collections.emptySet();
         MULTI_VALUE_PREFIXES = Collections.emptyMap();
diff --git 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientComponentConfigurer.java
 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientComponentConfigurer.java
index b28d4fe4fc69..055e23d8baf8 100644
--- 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientComponentConfigurer.java
+++ 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientComponentConfigurer.java
@@ -71,6 +71,7 @@ public class MiloClientComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "overrideHost": 
getOrCreateConfiguration(target).setOverrideHost(property(camelContext, 
boolean.class, value)); return true;
         case "overrideport":
         case "overridePort": 
getOrCreateConfiguration(target).setOverridePort(property(camelContext, 
boolean.class, value)); return true;
+        case "password": 
getOrCreateConfiguration(target).setPassword(property(camelContext, 
java.lang.String.class, value)); return true;
         case "producturi":
         case "productUri": 
getOrCreateConfiguration(target).setProductUri(property(camelContext, 
java.lang.String.class, value)); return true;
         case "requesttimeout":
@@ -81,6 +82,7 @@ public class MiloClientComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "sessionName": 
getOrCreateConfiguration(target).setSessionName(property(camelContext, 
java.lang.String.class, value)); return true;
         case "sessiontimeout":
         case "sessionTimeout": 
getOrCreateConfiguration(target).setSessionTimeout(property(camelContext, 
java.lang.Long.class, value)); return true;
+        case "username": 
getOrCreateConfiguration(target).setUsername(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
     }
@@ -134,6 +136,7 @@ public class MiloClientComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "overrideHost": return boolean.class;
         case "overrideport":
         case "overridePort": return boolean.class;
+        case "password": return java.lang.String.class;
         case "producturi":
         case "productUri": return java.lang.String.class;
         case "requesttimeout":
@@ -144,6 +147,7 @@ public class MiloClientComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "sessionName": return java.lang.String.class;
         case "sessiontimeout":
         case "sessionTimeout": return java.lang.Long.class;
+        case "username": return java.lang.String.class;
         default: return null;
         }
     }
@@ -193,6 +197,7 @@ public class MiloClientComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "overrideHost": return 
getOrCreateConfiguration(target).isOverrideHost();
         case "overrideport":
         case "overridePort": return 
getOrCreateConfiguration(target).isOverridePort();
+        case "password": return getOrCreateConfiguration(target).getPassword();
         case "producturi":
         case "productUri": return 
getOrCreateConfiguration(target).getProductUri();
         case "requesttimeout":
@@ -203,6 +208,7 @@ public class MiloClientComponentConfigurer extends 
PropertyConfigurerSupport imp
         case "sessionName": return 
getOrCreateConfiguration(target).getSessionName();
         case "sessiontimeout":
         case "sessionTimeout": return 
getOrCreateConfiguration(target).getSessionTimeout();
+        case "username": return getOrCreateConfiguration(target).getUsername();
         default: return null;
         }
     }
diff --git 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointConfigurer.java
 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointConfigurer.java
index d5f5c46560e7..971853e1a8e6 100644
--- 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointConfigurer.java
+++ 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointConfigurer.java
@@ -77,6 +77,7 @@ public class MiloClientEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "overrideHost": 
target.getConfiguration().setOverrideHost(property(camelContext, boolean.class, 
value)); return true;
         case "overrideport":
         case "overridePort": 
target.getConfiguration().setOverridePort(property(camelContext, boolean.class, 
value)); return true;
+        case "password": 
target.getConfiguration().setPassword(property(camelContext, 
java.lang.String.class, value)); return true;
         case "producturi":
         case "productUri": 
target.getConfiguration().setProductUri(property(camelContext, 
java.lang.String.class, value)); return true;
         case "requesttimeout":
@@ -89,6 +90,7 @@ public class MiloClientEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "sessionName": 
target.getConfiguration().setSessionName(property(camelContext, 
java.lang.String.class, value)); return true;
         case "sessiontimeout":
         case "sessionTimeout": 
target.getConfiguration().setSessionTimeout(property(camelContext, 
java.lang.Long.class, value)); return true;
+        case "username": 
target.getConfiguration().setUsername(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
         }
     }
@@ -150,6 +152,7 @@ public class MiloClientEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "overrideHost": return boolean.class;
         case "overrideport":
         case "overridePort": return boolean.class;
+        case "password": return java.lang.String.class;
         case "producturi":
         case "productUri": return java.lang.String.class;
         case "requesttimeout":
@@ -162,6 +165,7 @@ public class MiloClientEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "sessionName": return java.lang.String.class;
         case "sessiontimeout":
         case "sessionTimeout": return java.lang.Long.class;
+        case "username": return java.lang.String.class;
         default: return null;
         }
     }
@@ -224,6 +228,7 @@ public class MiloClientEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "overrideHost": return target.getConfiguration().isOverrideHost();
         case "overrideport":
         case "overridePort": return target.getConfiguration().isOverridePort();
+        case "password": return target.getConfiguration().getPassword();
         case "producturi":
         case "productUri": return target.getConfiguration().getProductUri();
         case "requesttimeout":
@@ -236,6 +241,7 @@ public class MiloClientEndpointConfigurer extends 
PropertyConfigurerSupport impl
         case "sessionName": return target.getConfiguration().getSessionName();
         case "sessiontimeout":
         case "sessionTimeout": return 
target.getConfiguration().getSessionTimeout();
+        case "username": return target.getConfiguration().getUsername();
         default: return null;
         }
     }
diff --git 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointUriFactory.java
 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointUriFactory.java
index c6a55f8b249c..575bfabdd798 100644
--- 
a/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointUriFactory.java
+++ 
b/components/camel-milo/src/generated/java/org/apache/camel/component/milo/client/MiloClientEndpointUriFactory.java
@@ -24,7 +24,7 @@ public class MiloClientEndpointUriFactory extends 
org.apache.camel.support.compo
     private static final Set<String> ENDPOINT_IDENTITY_PROPERTY_NAMES;
     private static final Map<String, String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(35);
+        Set<String> props = new HashSet<>(37);
         props.add("allowedSecurityPolicies");
         props.add("applicationName");
         props.add("applicationUri");
@@ -54,16 +54,19 @@ public class MiloClientEndpointUriFactory extends 
org.apache.camel.support.compo
         props.add("omitNullValues");
         props.add("overrideHost");
         props.add("overridePort");
+        props.add("password");
         props.add("productUri");
         props.add("requestTimeout");
         props.add("requestedPublishingInterval");
         props.add("samplingInterval");
         props.add("sessionName");
         props.add("sessionTimeout");
+        props.add("username");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
-        Set<String> secretProps = new HashSet<>(2);
+        Set<String> secretProps = new HashSet<>(3);
         secretProps.add("keyPassword");
         secretProps.add("keyStorePassword");
+        secretProps.add("password");
         SECRET_PROPERTY_NAMES = Collections.unmodifiableSet(secretProps);
         ENDPOINT_IDENTITY_PROPERTY_NAMES = Collections.emptySet();
         MULTI_VALUE_PREFIXES = Collections.emptyMap();
diff --git 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
index e7391bdcfd0a..aa643bd4b294 100644
--- 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
+++ 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/browse/milo-browse.json
@@ -48,7 +48,9 @@
     "requestedPublishingInterval": { "index": 21, "kind": "property", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in mi [...]
     "requestTimeout": { "index": 22, "kind": "property", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 23, "kind": "property", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 24, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 24, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 25, "kind": "property", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in the [...]
+    "username": { "index": 26, "kind": "property", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when th [...]
   },
   "headers": {
     "CamelMiloNodeIds": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"List", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ids.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_IDS" }
@@ -84,6 +86,8 @@
     "requestedPublishingInterval": { "index": 27, "kind": "parameter", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in m [...]
     "requestTimeout": { "index": 28, "kind": "parameter", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 29, "kind": "parameter", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 30, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 30, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 31, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in th [...]
+    "username": { "index": 32, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when t [...]
   }
 }
diff --git 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
index 73e3dabb3dd9..9b90876beadb 100644
--- 
a/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
+++ 
b/components/camel-milo/src/generated/resources/META-INF/org/apache/camel/component/milo/client/milo-client.json
@@ -49,7 +49,9 @@
     "requestedPublishingInterval": { "index": 22, "kind": "property", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in mi [...]
     "requestTimeout": { "index": 23, "kind": "property", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 24, "kind": "property", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 25, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 25, "kind": "property", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 26, "kind": "property", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in the [...]
+    "username": { "index": 27, "kind": "property", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when th [...]
   },
   "headers": {
     "CamelMiloNodeIds": { "index": 0, "kind": "header", "displayName": "", 
"group": "producer", "label": "producer", "required": false, "javaType": 
"List", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The node ids.", "constantName": 
"org.apache.camel.component.milo.MiloConstants#HEADER_NODE_IDS" },
@@ -90,6 +92,8 @@
     "requestedPublishingInterval": { "index": 31, "kind": "parameter", 
"displayName": "Requested Publishing Interval", "group": "client", "label": 
"client", "required": false, "type": "number", "javaType": "java.lang.Double", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"1_000.0", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The requested publishing 
interval in m [...]
     "requestTimeout": { "index": 32, "kind": "parameter", "displayName": 
"Request Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Request timeout in 
milliseconds" },
     "sessionName": { "index": 33, "kind": "parameter", "displayName": "Session 
Name", "group": "client", "label": "client", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session name" },
-    "sessionTimeout": { "index": 34, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" }
+    "sessionTimeout": { "index": 34, "kind": "parameter", "displayName": 
"Session Timeout", "group": "client", "label": "client", "required": false, 
"type": "integer", "javaType": "java.lang.Long", "deprecated": false, 
"autowired": false, "secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "Session timeout in 
milliseconds" },
+    "password": { "index": 35, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "security": "secret", "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The password for 
authentication. Use this instead of embedding credentials in th [...]
+    "username": { "index": 36, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "configurationClass": 
"org.apache.camel.component.milo.client.MiloClientConfiguration", 
"configurationField": "configuration", "description": "The username for 
authentication. Use this instead of embedding credentials in the endpoint URI 
when t [...]
   }
 }
diff --git a/components/camel-milo/src/main/docs/milo-client-component.adoc 
b/components/camel-milo/src/main/docs/milo-client-component.adoc
index 5035ef71595a..90ff4f0cb343 100644
--- a/components/camel-milo/src/main/docs/milo-client-component.adoc
+++ b/components/camel-milo/src/main/docs/milo-client-component.adoc
@@ -50,6 +50,20 @@ 
milo-client:opc.tcp://[user:password@]host:port?node=RAW(nsu=urn:foo:bar;s=item-
 
 If no user credentials are provided the client will switch to anonymous mode.
 
+As an alternative to URI-embedded credentials (`user:password`), you can 
provide
+credentials explicitly using the endpoint parameters `username` and `password`.
+This is recommended when credentials contain special characters (for example
+`?`, `/`, `@`, `&`, `%`(%25)) that can make URI-embedded credentials difficult 
to handle.
+
+For example:
+
+----
+milo-client:opc.tcp://host:port/path/to/service?node=RAW(nsu=urn:foo:bar;s=item-1)&username=RAW(my?user@name)&password=RAW(p@ss/w&rd)
+----
+
+When both styles are provided, the explicit `username`/`password` parameters 
take
+precedence over credentials embedded in the URI.
+
 All configuration options in the group +client+ are applicable to the shared 
client instance. Endpoints
 will share client instances for each endpoint URI. So the first time a request 
for that endpoint URI is
 made, the options of the +client+ group are applied. All further instances 
will be ignored.
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
index f5649a94fdd8..56d1534f0e73 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientConfiguration.java
@@ -113,6 +113,12 @@ public class MiloClientConfiguration implements Cloneable {
     @UriParam(label = "client", defaultValue = "1_000.0")
     private Double requestedPublishingInterval = 
DEFAULT_REQUESTED_PUBLISHING_INTERVAL;
 
+    @UriParam(label = "security")
+    private String username;
+
+    @UriParam(label = "security", security = "secret")
+    private String password;
+
     public MiloClientConfiguration() {
     }
 
@@ -138,6 +144,8 @@ public class MiloClientConfiguration implements Cloneable {
         this.overrideHost = other.overrideHost;
         this.overridePort = other.overridePort;
         this.requestedPublishingInterval = other.requestedPublishingInterval;
+        this.username = other.username;
+        this.password = other.password;
     }
 
     /**
@@ -415,6 +423,30 @@ public class MiloClientConfiguration implements Cloneable {
         this.requestedPublishingInterval = requestedPublishingInterval;
     }
 
+    /**
+     * The username for authentication. Use this instead of embedding 
credentials in the endpoint URI when the username
+     * contains special characters (such as {@code ?}, {@code /}, {@code @}, 
{@code &}).
+     */
+    public void setUsername(final String username) {
+        this.username = username;
+    }
+
+    public String getUsername() {
+        return this.username;
+    }
+
+    /**
+     * The password for authentication. Use this instead of embedding 
credentials in the endpoint URI when the password
+     * contains special characters (such as {@code ?}, {@code /}, {@code @}, 
{@code &}).
+     */
+    public void setPassword(final String password) {
+        this.password = password;
+    }
+
+    public String getPassword() {
+        return this.password;
+    }
+
     public Double getRequestedPublishingInterval() {
         return requestedPublishingInterval;
     }
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
index 6073a192a5f8..ae796c746d6c 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/MiloClientEndpoint.java
@@ -203,4 +203,24 @@ public class MiloClientEndpoint extends DefaultEndpoint {
     public void setOmitNullValues(boolean omitNullValues) {
         this.omitNullValues = omitNullValues;
     }
+
+    public String getUsername() {
+        return configuration != null ? configuration.getUsername() : null;
+    }
+
+    public void setUsername(String username) {
+        if (configuration != null) {
+            configuration.setUsername(username);
+        }
+    }
+
+    public String getPassword() {
+        return configuration != null ? configuration.getPassword() : null;
+    }
+
+    public void setPassword(String password) {
+        if (configuration != null) {
+            configuration.setPassword(password);
+        }
+    }
 }
diff --git 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
index b5b14bbcddb2..75d6ec23f0b9 100644
--- 
a/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
+++ 
b/components/camel-milo/src/main/java/org/apache/camel/component/milo/client/internal/SubscriptionManager.java
@@ -694,18 +694,17 @@ public class SubscriptionManager {
     private Connected performConnect() throws Exception {
 
         // eval endpoint
-
         String discoveryUri = getEndpointDiscoveryUri();
 
         final URI uri = URI.create(getEndpointDiscoveryUri());
 
-        // milo library doesn't allow user info as a part of the uri, it has to
-        // be
-        // removed before sending to milo
+        // Extracting/removing user:password string from the full URL is 
error-prone with special characters,
+        // because of that the discovery URL is rebuilt from URI parts.
+        discoveryUri
+                = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), 
uri.getPath(), uri.getQuery(), uri.getFragment())
+                        .toString();
         final String user = uri.getUserInfo();
-        if (user != null && !user.isEmpty()) {
-            discoveryUri = discoveryUri.replaceFirst(user + "@", "");
-        }
+
         LOG.debug("Discovering endpoints from: {}", discoveryUri);
 
         final EndpointDescription endpoint = 
DiscoveryClient.getEndpoints(discoveryUri).thenApply(endpoints -> {
@@ -728,14 +727,21 @@ public class SubscriptionManager {
         // set identity providers
         final List<IdentityProvider> providers = new LinkedList<>();
 
-        if (user != null && !user.isEmpty()) {
+        // prefer explicit username/password parameters over URI-embedded 
credentials
+        // to avoid issues with special characters in the URI
+        final String explicitUsername = this.configuration.getUsername();
+        final String explicitPassword = this.configuration.getPassword();
+        if (explicitUsername != null && !explicitUsername.isEmpty()) {
+            LOG.debug("Enable username/password provider (explicit parameter): 
{}", explicitUsername);
+            providers.add(new UsernameProvider(explicitUsername, 
explicitPassword != null ? explicitPassword : ""));
+        } else if (user != null && !user.isEmpty()) {
             final String[] creds = user.split(":", 2);
             if (creds != null) {
                 if (creds.length == 2) {
                     LOG.debug("Enable username/password provider: {}", 
creds[0]);
                 }
 
-                providers.add(new UsernameProvider(creds[0], creds[1]));
+                providers.add(new UsernameProvider(creds[0], creds.length == 2 
? creds[1] : ""));
             }
         }
 
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
index e9d13236b2cb..6c255aec3331 100644
--- 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/AbstractMiloServerTest.java
@@ -44,6 +44,20 @@ public abstract class AbstractMiloServerTest extends 
CamelTestSupport {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(AbstractMiloServerTest.class);
 
+    // Password with special characters (@ $ ? & / # % (URL escaped: %25) . : 
* and non-ASCII ö) to verify
+    // that the credential parser handles delimiters and URI-sensitive chars 
correctly
+    protected static final String SPECIAL_CHAR_CREDENTIAL = 
"pass@$?&/#%25.:*wörd3";
+
+    // Username with special characters ($ and non-ASCII ü) to verify that 
usernames
+    // containing non-alphanumeric and non-ASCII characters are parsed 
correctly
+    protected static final String SPECIAL_CHAR_USER = "üs$er4";
+
+    // Comma-separated "user:pass" pairs: two plain, one with special-char 
password and special-char username
+    private static final String TEST_CREDENTIALS = String.join(",",
+            "foo:bar",
+            "foo2:bar2",
+            SPECIAL_CHAR_USER + ":" + SPECIAL_CHAR_CREDENTIAL);
+
     @RegisterExtension
     AvailablePortFinder.Port serverPortHolder = AvailablePortFinder.find();
 
@@ -109,7 +123,7 @@ public abstract class AbstractMiloServerTest extends 
CamelTestSupport {
     protected void configureMiloServer(final MiloServerComponent server) 
throws Exception {
         server.setBindAddresses("localhost");
         server.setPort(getServerPort());
-        server.setUserAuthenticationCredentials("foo:bar,foo2:bar2");
+        server.setUserAuthenticationCredentials(TEST_CREDENTIALS);
         server.setUsernameSecurityPolicyUri(SecurityPolicy.None);
         server.setSecurityPoliciesById("None");
         server.setEnableAnonymousAuthentication(true);
diff --git 
a/components/camel-milo/src/test/java/org/apache/camel/component/milo/ExplicitCredentialsTest.java
 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/ExplicitCredentialsTest.java
new file mode 100644
index 000000000000..a007c42a247d
--- /dev/null
+++ 
b/components/camel-milo/src/test/java/org/apache/camel/component/milo/ExplicitCredentialsTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.milo;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.milo.server.MiloServerComponent;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
+import org.eclipse.milo.opcua.stack.core.types.builtin.Variant;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.milo.NodeIds.nodeValue;
+
+/**
+ * Verifies that explicit username/password endpoint parameters work 
correctly, especially when credentials contain
+ * special characters (such as {@code ?}, {@code &}, {@code @}) that would 
break URI-embedded credentials.
+ */
+public class ExplicitCredentialsTest extends AbstractMiloServerTest {
+
+    private static final String MILO_SERVER_ITEM = "milo-server:myitem1";
+
+    // Use explicit username/password parameters instead of embedding in URI
+    private static final String MILO_CLIENT_ITEM
+            = "milo-client:opc.tcp://localhost:@@port@@?node="
+              + nodeValue(MiloServerComponent.DEFAULT_NAMESPACE_URI, "myitem1")
+              + "&overrideHost=true&allowedSecurityPolicies=None"
+              + "&username=RAW(" + SPECIAL_CHAR_USER + ")"
+              + "&password=RAW(" + SPECIAL_CHAR_CREDENTIAL + ")";
+
+    private static final String MOCK_RESULT = 
"mock:complex_credentials_result";
+
+    @Override
+    protected void configureMiloServer(final MiloServerComponent server) 
throws Exception {
+        server.setBindAddresses("localhost");
+        server.setPort(getServerPort());
+        // register credentials with special characters
+        server.setUserAuthenticationCredentials(SPECIAL_CHAR_USER + ":" + 
SPECIAL_CHAR_CREDENTIAL);
+        server.setUsernameSecurityPolicyUri(SecurityPolicy.None);
+        server.setSecurityPoliciesById("None");
+        server.setEnableAnonymousAuthentication(false);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from(MILO_SERVER_ITEM).to(MOCK_RESULT);
+                from("direct:start").to(resolve(MILO_CLIENT_ITEM));
+            }
+        };
+    }
+
+    @Test
+    void 
shouldAuthenticateWithExplicitCredentialsContainingSpecialCharacters() throws 
Exception {
+
+        final String testBody = "test_special_chars";
+
+        MockEndpoint mock = getMockEndpoint(MOCK_RESULT);
+        mock.expectedMessageCount(1);
+        testBody(mock.message(0), assertGoodValue(testBody));
+
+        // write synchronously so the server receives the value before 
assertion
+        template.sendBodyAndHeader("direct:start", new Variant(testBody), 
"CamelMiloAwait", true);
+
+        // verify that the message sent via the client was received by the 
server endpoint
+        mock.assertIsSatisfied();
+    }
+}
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloBrowseComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloBrowseComponentBuilderFactory.java
index 27dba5d36c3a..7f9b98d8a879 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloBrowseComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloBrowseComponentBuilderFactory.java
@@ -461,6 +461,40 @@ public interface MiloBrowseComponentBuilderFactory {
             doSetProperty("sessionTimeout", sessionTimeout);
             return this;
         }
+    
+        /**
+         * The password for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the password contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param password the value to set
+         * @return the dsl builder
+         */
+        default MiloBrowseComponentBuilder password(java.lang.String password) 
{
+            doSetProperty("password", password);
+            return this;
+        }
+    
+        /**
+         * The username for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the username contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param username the value to set
+         * @return the dsl builder
+         */
+        default MiloBrowseComponentBuilder username(java.lang.String username) 
{
+            doSetProperty("username", username);
+            return this;
+        }
     }
 
     class MiloBrowseComponentBuilderImpl
@@ -507,6 +541,8 @@ public interface MiloBrowseComponentBuilderFactory {
             case "requestTimeout": 
getOrCreateConfiguration((MiloBrowseComponent) 
component).setRequestTimeout((java.lang.Long) value); return true;
             case "sessionName": getOrCreateConfiguration((MiloBrowseComponent) 
component).setSessionName((java.lang.String) value); return true;
             case "sessionTimeout": 
getOrCreateConfiguration((MiloBrowseComponent) 
component).setSessionTimeout((java.lang.Long) value); return true;
+            case "password": getOrCreateConfiguration((MiloBrowseComponent) 
component).setPassword((java.lang.String) value); return true;
+            case "username": getOrCreateConfiguration((MiloBrowseComponent) 
component).setUsername((java.lang.String) value); return true;
             default: return false;
             }
         }
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloClientComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloClientComponentBuilderFactory.java
index d5ec2da4cd01..44d22e8023a0 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloClientComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/MiloClientComponentBuilderFactory.java
@@ -489,6 +489,40 @@ public interface MiloClientComponentBuilderFactory {
             doSetProperty("sessionTimeout", sessionTimeout);
             return this;
         }
+    
+        /**
+         * The password for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the password contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param password the value to set
+         * @return the dsl builder
+         */
+        default MiloClientComponentBuilder password(java.lang.String password) 
{
+            doSetProperty("password", password);
+            return this;
+        }
+    
+        /**
+         * The username for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the username contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: security
+         * 
+         * @param username the value to set
+         * @return the dsl builder
+         */
+        default MiloClientComponentBuilder username(java.lang.String username) 
{
+            doSetProperty("username", username);
+            return this;
+        }
     }
 
     class MiloClientComponentBuilderImpl
@@ -536,6 +570,8 @@ public interface MiloClientComponentBuilderFactory {
             case "requestTimeout": 
getOrCreateConfiguration((MiloClientComponent) 
component).setRequestTimeout((java.lang.Long) value); return true;
             case "sessionName": getOrCreateConfiguration((MiloClientComponent) 
component).setSessionName((java.lang.String) value); return true;
             case "sessionTimeout": 
getOrCreateConfiguration((MiloClientComponent) 
component).setSessionTimeout((java.lang.Long) value); return true;
+            case "password": getOrCreateConfiguration((MiloClientComponent) 
component).setPassword((java.lang.String) value); return true;
+            case "username": getOrCreateConfiguration((MiloClientComponent) 
component).setUsername((java.lang.String) value); return true;
             default: return false;
             }
         }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloBrowseEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloBrowseEndpointBuilderFactory.java
index e6f1115f48cb..76ff5d3c3969 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloBrowseEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloBrowseEndpointBuilderFactory.java
@@ -685,6 +685,38 @@ public interface MiloBrowseEndpointBuilderFactory {
             doSetProperty("sessionTimeout", sessionTimeout);
             return this;
         }
+        /**
+         * The password for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the password contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param password the value to set
+         * @return the dsl builder
+         */
+        default MiloBrowseEndpointBuilder password(String password) {
+            doSetProperty("password", password);
+            return this;
+        }
+        /**
+         * The username for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the username contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param username the value to set
+         * @return the dsl builder
+         */
+        default MiloBrowseEndpointBuilder username(String username) {
+            doSetProperty("username", username);
+            return this;
+        }
     }
 
     /**
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloClientEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloClientEndpointBuilderFactory.java
index cb5c63bb4a94..8c00914b1ba4 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloClientEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/MiloClientEndpointBuilderFactory.java
@@ -709,6 +709,38 @@ public interface MiloClientEndpointBuilderFactory {
             doSetProperty("sessionTimeout", sessionTimeout);
             return this;
         }
+        /**
+         * The password for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the password contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param password the value to set
+         * @return the dsl builder
+         */
+        default MiloClientEndpointConsumerBuilder password(String password) {
+            doSetProperty("password", password);
+            return this;
+        }
+        /**
+         * The username for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the username contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param username the value to set
+         * @return the dsl builder
+         */
+        default MiloClientEndpointConsumerBuilder username(String username) {
+            doSetProperty("username", username);
+            return this;
+        }
     }
 
     /**
@@ -1514,6 +1546,38 @@ public interface MiloClientEndpointBuilderFactory {
             doSetProperty("sessionTimeout", sessionTimeout);
             return this;
         }
+        /**
+         * The password for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the password contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param password the value to set
+         * @return the dsl builder
+         */
+        default MiloClientEndpointProducerBuilder password(String password) {
+            doSetProperty("password", password);
+            return this;
+        }
+        /**
+         * The username for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the username contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param username the value to set
+         * @return the dsl builder
+         */
+        default MiloClientEndpointProducerBuilder username(String username) {
+            doSetProperty("username", username);
+            return this;
+        }
     }
 
     /**
@@ -2248,6 +2312,38 @@ public interface MiloClientEndpointBuilderFactory {
             doSetProperty("sessionTimeout", sessionTimeout);
             return this;
         }
+        /**
+         * The password for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the password contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param password the value to set
+         * @return the dsl builder
+         */
+        default MiloClientEndpointBuilder password(String password) {
+            doSetProperty("password", password);
+            return this;
+        }
+        /**
+         * The username for authentication. Use this instead of embedding
+         * credentials in the endpoint URI when the username contains special
+         * characters (such as {code }, {code /}, {code }, {code &amp;}).
+         * 
+         * The option is a: <code>java.lang.String</code> type.
+         * 
+         * Group: security
+         * 
+         * @param username the value to set
+         * @return the dsl builder
+         */
+        default MiloClientEndpointBuilder username(String username) {
+            doSetProperty("username", username);
+            return this;
+        }
     }
 
     /**

Reply via email to