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 ea62eb669e6b CAMEL-23594: camel-kamelet - Fix kamelet properties being 
URL-encoded in YAML DSL
ea62eb669e6b is described below

commit ea62eb669e6b65a92b17e79e4377e904af9eb0e9
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Jun 22 11:44:46 2026 +0200

    CAMEL-23594: camel-kamelet - Fix kamelet properties being URL-encoded in 
YAML DSL
    
    The YAML DSL was URL-encoding kamelet parameters via
    URISupport.createQueryString() (encode=true by default), but
    KameletComponent uses useRawUri()=true so the encoding was never
    reversed. This caused values like application/json to arrive as
    application%2Fjson in kamelet templates.
    
    Skip encoding for kamelet URIs in YamlRoutesBuilderLoader, matching
    what KameletDeserializer and YamlSupport already do with
    createQueryString(params, false).
    
    Supersedes #23391.
    
    Closes #24170
    
    Co-Authored-By: Claude <[email protected]>
---
 .../ROOT/pages/camel-4x-upgrade-guide-4_21.adoc    | 10 +++++++
 .../camel/dsl/yaml/YamlRoutesBuilderLoader.java    |  3 ++-
 .../org/apache/camel/dsl/yaml/KameletTest.groovy   | 31 ++++++++++++++++++++++
 .../dsl/yaml/PipeLoaderErrorHandlerTest.groovy     |  8 +++---
 .../apache/camel/dsl/yaml/PipeLoaderTest.groovy    | 22 +++++++--------
 5 files changed, 58 insertions(+), 16 deletions(-)

diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
index eb06df2d01e4..eb57a78ee4b4 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_21.adoc
@@ -451,6 +451,16 @@ defense-in-depth only. The primary mitigation should be 
configured at the messag
 * ActiveMQ Artemis: `deserializationAllowList` / `deserializationDenyList` 
(see the Artemis docs)
 * ActiveMQ Classic: the `org.apache.activemq.SERIALIZABLE_PACKAGES` system 
property
 
+=== camel-kamelet
+
+Kamelet endpoint URIs constructed from YAML DSL `parameters:` blocks are no 
longer URL-encoded at runtime.
+Previously, property values containing special characters (such as `/`) were 
incorrectly URL-encoded
+(e.g., `application/json` became `application%2Fjson`), which caused issues 
because the Kamelet component
+uses raw URIs and does not decode them. This fix aligns the YAML DSL 
`parameters:` handling with how
+inline kamelet URIs (e.g., `kamelet:myKamelet?key=value`) already work.
+
+If you have workarounds in place to deal with encoded kamelet property values, 
they can be removed.
+
 === camel-jms
 
 JMS `ObjectMessage` support is now disabled by default. Java object 
serialization is a recurring source
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
index 16862746b179..feab814755ab 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
@@ -603,7 +603,8 @@ public class YamlRoutesBuilderLoader extends 
YamlRoutesBuilderLoaderSupport {
         }
 
         if (params != null && !params.isEmpty()) {
-            String query = URISupport.createQueryString(params);
+            // kamelet uses useRawUri so parameters should not be encoded
+            String query = URISupport.createQueryString(params, !kamelet);
             // CAMEL-23284: restore property placeholders that were URL-encoded
             query = query.replace("%7B%7B", "{{").replace("%7D%7D", "}}");
             uri = uri + "?" + query;
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
index b9ef38fcb29a..05b913beeebc 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
@@ -390,4 +390,35 @@ class KameletTest extends YamlTestSupport {
         then:
             MockEndpoint.assertIsSatisfied(context)
     }
+
+    def "kamelet (properties not url encoded)"() {
+        setup:
+            addTemplate('setPayloadWithType') {
+                from('kamelet:source')
+                    .setBody().simple('{{contentType}}')
+                    .to("kamelet:sink")
+            }
+
+            loadRoutes '''
+                - from:
+                    uri: "direct:start"
+                    steps:
+                      - kamelet:
+                          name: "setPayloadWithType"
+                          parameters:
+                            contentType: "application/json"
+                      - to: "mock:result"
+            '''
+
+            withMock('mock:result') {
+                expectedMessageCount 1
+                expectedBodiesReceived 'application/json'
+            }
+        when:
+            withTemplate {
+                to('direct:start').withBody('hello').send()
+            }
+        then:
+            MockEndpoint.assertIsSatisfied(context)
+    }
 }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderErrorHandlerTest.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderErrorHandlerTest.groovy
index 5f068ae0f5fc..c0dcf4647112 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderErrorHandlerTest.groovy
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderErrorHandlerTest.groovy
@@ -79,11 +79,11 @@ class PipeLoaderErrorHandlerTest extends YamlTestSupport {
             errorHandlerFactory != null
             errorHandlerFactory instanceof DeadLetterChannelDefinition
             var eh = errorHandlerFactory as DeadLetterChannelDefinition
-            eh.deadLetterUri == 
'kamelet:error-handler?kafkaTopic=my-first-test&logMessage=ERROR%21&kafkaServiceAccountId=scott&kafkaBrokers=my-broker&kafkaServiceAccountSecret=tiger'
+            eh.deadLetterUri == 
'kamelet:error-handler?kafkaTopic=my-first-test&logMessage=ERROR!&kafkaServiceAccountId=scott&kafkaBrokers=my-broker&kafkaServiceAccountSecret=tiger'
             eh.redeliveryPolicy.maximumRedeliveries == "1"
             eh.redeliveryPolicy.redeliveryDelay == "2000"
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 'kamelet:log-sink'
@@ -189,7 +189,7 @@ class PipeLoaderErrorHandlerTest extends YamlTestSupport {
             eh.redeliveryPolicy.redeliveryDelay == "2000"
             eh.getUseOriginalMessage() == "true"
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 'kamelet:log-sink'
@@ -231,7 +231,7 @@ class PipeLoaderErrorHandlerTest extends YamlTestSupport {
             errorHandlerFactory != null
             errorHandlerFactory instanceof NoErrorHandlerDefinition
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 'kamelet:log-sink'
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
index 64c7f6705dc5..66af9b152ab6 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
@@ -53,7 +53,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
             with (context.routeDefinitions[0]) {
                 routeId == 'timer-event-source'
-                input.endpointUri == 
'kamelet:timer-source?message=Hello+world%21'
+                input.endpointUri == 'kamelet:timer-source?message=Hello 
world!'
                 input.lineNumber == 7
                 outputs.size() == 1
                 with (outputs[0], ToDefinition) {
@@ -294,7 +294,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 'kafka:my-topic'
@@ -352,11 +352,11 @@ class PipeLoaderTest extends YamlTestSupport {
             errorHandlerFactory != null
             errorHandlerFactory instanceof DeadLetterChannelDefinition
             var eh = errorHandlerFactory as DeadLetterChannelDefinition
-            eh.deadLetterUri == 
'kamelet:error-handler?kafkaTopic=my-first-test&logMessage=ERROR%21&kafkaServiceAccountId=scott&kafkaBrokers=my-broker&kafkaServiceAccountSecret=tiger'
+            eh.deadLetterUri == 
'kamelet:error-handler?kafkaTopic=my-first-test&logMessage=ERROR!&kafkaServiceAccountId=scott&kafkaBrokers=my-broker&kafkaServiceAccountSecret=tiger'
             eh.redeliveryPolicy.maximumRedeliveries == "1"
             eh.redeliveryPolicy.redeliveryDelay == "2000"
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 'kamelet:log-sink'
@@ -395,7 +395,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 'knative:channel/my-messages'
@@ -475,7 +475,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             outputs.size() == 1
             with (outputs[0], ToDefinition) {
                 endpointUri == 
'knative:event/org.apache.camel.event.messages?kind=Broker&name=foo-broker'
@@ -585,7 +585,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             input.lineNumber == 7
             outputs.size() == 1
             with (outputs[0], KameletDefinition) {
@@ -627,7 +627,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             input.lineNumber == 7
             inputType.urn == 'text/plain'
             outputType.urn == 'application/octet-stream'
@@ -673,7 +673,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             input.lineNumber == 7
             inputType.urn == 'camel:text/plain'
             outputType.urn == 'camel:application/octet-stream'
@@ -717,7 +717,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             input.lineNumber == 7
             outputs.size() == 3
             with (outputs[0], TransformDataTypeDefinition) {
@@ -769,7 +769,7 @@ class PipeLoaderTest extends YamlTestSupport {
 
         with (context.routeDefinitions[0]) {
             routeId == 'timer-event-source'
-            input.endpointUri == 'kamelet:timer-source?message=Hello+world%21'
+            input.endpointUri == 'kamelet:timer-source?message=Hello world!'
             input.lineNumber == 7
             outputs.size() == 3
             with (outputs[0], TransformDataTypeDefinition) {

Reply via email to