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 990065a16573 CAMEL-24077: camel-amqp - Only append SSL transport 
options when configured and URL-encode values (#24736)
990065a16573 is described below

commit 990065a16573e90e87aef965884b99efdc571879
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jul 15 18:03:56 2026 +0200

    CAMEL-24077: camel-amqp - Only append SSL transport options when configured 
and URL-encode values (#24736)
    
    With useSsl=true and no explicit trust/key store, all six transport.*
    options were appended with empty strings, causing Qpid JMS to throw
    FileNotFoundException instead of using the JVM default trust store.
    Now only appends transport options when the corresponding store
    location is configured. Also URL-encodes values to prevent URI
    corruption from special characters in store paths or passwords.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .../apache/camel/component/amqp/AMQPComponent.java | 30 ++++++++++++---
 .../camel/component/amqp/AMQPConfigTest.java       | 43 +++++++++++++++++++++-
 2 files changed, 65 insertions(+), 8 deletions(-)

diff --git 
a/components/camel-amqp/src/main/java/org/apache/camel/component/amqp/AMQPComponent.java
 
b/components/camel-amqp/src/main/java/org/apache/camel/component/amqp/AMQPComponent.java
index fff7f6204dd2..145e7ab5693a 100644
--- 
a/components/camel-amqp/src/main/java/org/apache/camel/component/amqp/AMQPComponent.java
+++ 
b/components/camel-amqp/src/main/java/org/apache/camel/component/amqp/AMQPComponent.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.amqp;
 
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
 import java.util.Set;
 
@@ -116,12 +118,24 @@ public class AMQPComponent extends JmsComponent {
             sb.append(useSsl == Boolean.TRUE ? "amqps://" : "amqp://");
             sb.append(host == null ? AMQP_DEFAULT_HOST : 
host).append(":").append(port == null ? AMQP_DEFAULT_PORT : port);
             if (useSsl == Boolean.TRUE) {
-                
sb.append("?transport.trustStoreLocation=").append(trustStoreLocation == null ? 
"" : trustStoreLocation);
-                sb.append("&transport.trustStoreType=").append(trustStoreType);
-                
sb.append("&transport.trustStorePassword=").append(trustStorePassword == null ? 
"" : trustStorePassword);
-                
sb.append("&transport.keyStoreLocation=").append(keyStoreLocation == null ? "" 
: keyStoreLocation);
-                sb.append("&transport.keyStoreType=").append(keyStoreType);
-                
sb.append("&transport.keyStorePassword=").append(keyStorePassword == null ? "" 
: keyStorePassword);
+                boolean first = true;
+                if (trustStoreLocation != null) {
+                    sb.append('?');
+                    first = false;
+                    
sb.append("transport.trustStoreLocation=").append(urlEncode(trustStoreLocation));
+                    
sb.append("&transport.trustStoreType=").append(urlEncode(trustStoreType));
+                    if (trustStorePassword != null) {
+                        
sb.append("&transport.trustStorePassword=").append(urlEncode(trustStorePassword));
+                    }
+                }
+                if (keyStoreLocation != null) {
+                    sb.append(first ? '?' : '&');
+                    
sb.append("transport.keyStoreLocation=").append(urlEncode(keyStoreLocation));
+                    
sb.append("&transport.keyStoreType=").append(urlEncode(keyStoreType));
+                    if (keyStorePassword != null) {
+                        
sb.append("&transport.keyStorePassword=").append(urlEncode(keyStorePassword));
+                    }
+                }
             }
             JmsConnectionFactory connectionFactory
                     = new JmsConnectionFactory(getUsername(), getPassword(), 
sb.toString());
@@ -282,4 +296,8 @@ public class AMQPComponent extends JmsComponent {
     public void setTrustStorePassword(String trustStorePassword) {
         this.trustStorePassword = trustStorePassword;
     }
+
+    private static String urlEncode(String value) {
+        return URLEncoder.encode(value, StandardCharsets.UTF_8);
+    }
 }
diff --git 
a/components/camel-amqp/src/test/java/org/apache/camel/component/amqp/AMQPConfigTest.java
 
b/components/camel-amqp/src/test/java/org/apache/camel/component/amqp/AMQPConfigTest.java
index eefdce6f9044..b23bd57d62e5 100644
--- 
a/components/camel-amqp/src/test/java/org/apache/camel/component/amqp/AMQPConfigTest.java
+++ 
b/components/camel-amqp/src/test/java/org/apache/camel/component/amqp/AMQPConfigTest.java
@@ -100,10 +100,36 @@ public class AMQPConfigTest {
         JmsConnectionFactory connectionFactory = (JmsConnectionFactory) 
amqpSslEnabledComponent.getConnectionFactory();
         assertNull(connectionFactory.getUsername());
         assertNull(connectionFactory.getPassword());
+        assertEquals("amqps://localhost:5672", 
connectionFactory.getRemoteURI());
+        assertEquals("topic://", connectionFactory.getTopicPrefix());
+    }
+
+    @Test
+    public void testTrustStoreOnlySslComponent() {
+        AMQPComponent component
+                = 
contextExtension.getContext().getComponent("amqps-trustonly", 
AMQPComponent.class);
+        assertTrue(component.getUseSsl());
+        assertEquals("server-ca-truststore.p12", 
component.getTrustStoreLocation());
+        assertNull(component.getKeyStoreLocation());
+
+        assertTrue(component.getConnectionFactory() instanceof 
JmsConnectionFactory);
+        JmsConnectionFactory connectionFactory = (JmsConnectionFactory) 
component.getConnectionFactory();
         assertEquals(
-                
"amqps://localhost:5672?transport.trustStoreLocation=&transport.trustStoreType=JKS&transport.trustStorePassword=&transport.keyStoreLocation=&transport.keyStoreType=JKS&transport.keyStorePassword=",
+                
"amqps://localhost:5672?transport.trustStoreLocation=server-ca-truststore.p12&transport.trustStoreType=PKCS12&transport.trustStorePassword=securepass",
+                connectionFactory.getRemoteURI());
+    }
+
+    @Test
+    public void testSslUrlEncodedPassword() {
+        AMQPComponent component
+                = 
contextExtension.getContext().getComponent("amqps-specialchars", 
AMQPComponent.class);
+        assertTrue(component.getUseSsl());
+
+        assertTrue(component.getConnectionFactory() instanceof 
JmsConnectionFactory);
+        JmsConnectionFactory connectionFactory = (JmsConnectionFactory) 
component.getConnectionFactory();
+        assertEquals(
+                
"amqps://localhost:5672?transport.trustStoreLocation=%2Fpath%2Fto%2Fstore.jks&transport.trustStoreType=JKS&transport.trustStorePassword=p%40ss%3Dw%26rd",
                 connectionFactory.getRemoteURI());
-        assertEquals("topic://", connectionFactory.getTopicPrefix());
     }
 
     @Test
@@ -157,6 +183,19 @@ public class AMQPConfigTest {
         amqpSslEnabledComponent.setUseSsl(true);
         context.addComponent("amqps-enabled", amqpSslEnabledComponent);
 
+        AMQPComponent amqpTrustOnlyComponent = new AMQPComponent();
+        amqpTrustOnlyComponent.setUseSsl(true);
+        
amqpTrustOnlyComponent.setTrustStoreLocation("server-ca-truststore.p12");
+        amqpTrustOnlyComponent.setTrustStorePassword("securepass");
+        amqpTrustOnlyComponent.setTrustStoreType("PKCS12");
+        context.addComponent("amqps-trustonly", amqpTrustOnlyComponent);
+
+        AMQPComponent amqpSpecialCharsComponent = new AMQPComponent();
+        amqpSpecialCharsComponent.setUseSsl(true);
+        amqpSpecialCharsComponent.setTrustStoreLocation("/path/to/store.jks");
+        amqpSpecialCharsComponent.setTrustStorePassword("p@ss=w&rd");
+        context.addComponent("amqps-specialchars", amqpSpecialCharsComponent);
+
         AMQPComponent amqpPortOnlyComponent = new AMQPComponent();
         amqpPortOnlyComponent.setPort(5556);
         context.addComponent("amqp-portonly", amqpPortOnlyComponent);

Reply via email to