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 &}).
+ *
+ * The option is a: <code>java.lang.String</code> 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 &}).
+ *
+ * The option is a: <code>java.lang.String</code> 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 &}).
+ *
+ * The option is a: <code>java.lang.String</code> 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 &}).
+ *
+ * The option is a: <code>java.lang.String</code> 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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 &}).
+ *
+ * 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;
+ }
}
/**