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 76b1e7235f3e CAMEL-26594: camel-yaml-dsl - a value under parameters: 
with an & is kept whole in the endpoint uri (#29185)
76b1e7235f3e is described below

commit 76b1e7235f3efbc7bccbda4db0424914e4680eb1
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Nov 4 20:00:59 2026 +0100

    CAMEL-26594: camel-yaml-dsl - a value under parameters: with an & is kept 
whole in the endpoint uri (#29185)
    
    - CAMEL-26594: camel-yaml-dsl - a value under parameters: with an & is kept 
whole in the endpoint uri
    - CAMEL-26594: camel-jbang - AI tools: a value under parameters: with an & 
is accepted, as the YAML DSL now keeps it whole
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../org/apache/camel/catalog/docs/yaml-dsl.adoc    |  27 ++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  20 ++
 .../dsl/jbang/core/commands/ai/EndpointChecks.java | 124 +++++--
 .../commands/ai/SourceValidatorEndpointTest.java   | 125 +++++--
 .../apache/camel/dsl/yaml/common/YamlSupport.java  |  74 +++-
 .../yaml/deserializers/KameletDeserializer.java    |   4 +-
 dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml          |   5 +
 .../camel-yaml-dsl/src/main/docs/yaml-dsl.adoc     |  27 ++
 .../camel/dsl/yaml/ParametersAmpersandTest.java    | 382 +++++++++++++++++++++
 9 files changed, 739 insertions(+), 49 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/yaml-dsl.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/yaml-dsl.adoc
index b5af1c7c832a..56d7f9d26463 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/yaml-dsl.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/yaml-dsl.adoc
@@ -320,6 +320,33 @@ To define an endpoint with the YAML dsl you have two 
options:
               authorizationToken: "XXX"
 ----
 
+=== Values with an & in parameters
+
+*Available as of Camel 4.24*
+
+A value under `parameters` is added to the query of the endpoint uri. When the 
value has an `&`, Camel puts it in
+`RAW(...)`, as it does for a secret option, so the `&` does not end the value. 
For example a file filter:
+
+[source,yaml]
+----
+- route:
+    from:
+      uri: "file:inbox"
+      parameters:
+        filterFile: "${file:name} contains 'R&D' && ${file:size} > 0"
+      steps:
+        - to:
+            uri: "log:rd"
+----
+
+The value is then taken as it is written, so a `+` in it stays a `+`. In a 
value without an `&`, a `+` is read as a
+space, as in a uri. Camel does not change a value that starts with `#` (a bean 
reference), a value in `RAW(...)` or
+`RAW{...}` already, and a path parameter, such as `directoryName` when the 
`uri` is only `file`.
+
+NOTE: Camel sees the `&` only when it is written in the YAML as the value of 
an option. When it comes from a property
+placeholder, or is in a value of a map option (see below), write the value in 
RAW yourself, such as
+`+RAW({{filter}})+`.
+
 === Map values for parameters
 
 *Available as of Camel 4.15*
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 6853e0c9fed9..d08605de8402 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -2114,6 +2114,26 @@ level when the dump was loaded (the rest configuration 
or the rest, the error ha
 configuration, the CamelContext), so the route behaved differently, or, for 
`apiDocs`, a verb with `apiDocs="true"`
 under a rest with `apiDocs="false"` was left out of the OpenAPI document.
 
+=== camel-yaml-dsl - a value under parameters: with an & is kept whole
+
+In the YAML DSL, a value under `parameters:` that has an `&` is now kept whole 
in the endpoint uri. Before, the value
+was cut at the `&`, and the rest was read as another option. For example, with
+`+filterFile: "${file:name} contains 'R&D'"+` the route failed to start. A 
lenient component, such as a Kamelet, got
+only the text before the `&`, without an error.
+
+Camel now puts such a value in `RAW(...)` in the uri, as it does for a secret 
option. When the value has `)&`, Camel
+uses `RAW{...}`. The value is then taken as it is written, so a `+` in it 
stays a `+`. A value without an `&` is read
+as before, so a `+` in it is a space (such as in a cron expression written 
with `+`).
+
+This applies to the endpoints of `from`, `to`, `toD`, `wireTap`, `poll` and 
`switch`, and to the `kamelet` EIP. Camel
+does not change a value that starts with `#` (a bean reference), a value in 
`RAW(...)` or `RAW{...}` already, or a path
+parameter, such as `directoryName` when the `uri` is only `file`: an `&` does 
no harm in the path. A route dump, such as
+`camel validate normalize`, writes such a value in RAW.
+
+Camel sees the `&` only when it is written in the YAML as the value of an 
option. When the `&` comes from a property
+placeholder, or is in a value of a map option (such as 
`additionalProperties`), write the value in RAW yourself, such
+as `+RAW({{name}})+`.
+
 === camel-jbang - camel get bean, get route-controller and top source
 
 * `camel get bean --dsl` shows the configuration of each property next to that 
property: it paired them by position,
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/EndpointChecks.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/EndpointChecks.java
index 3f7f2204d426..4fb7b8f7769c 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/EndpointChecks.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/EndpointChecks.java
@@ -61,6 +61,13 @@ final class EndpointChecks {
             = Set.of("to", "toD", "to-d", "wireTap", "wire-tap", "enrich",
                     "interceptSendToEndpoint", "intercept-send-to-endpoint");
 
+    /**
+     * Why a value cannot be put in RAW, for a value that has both )& and }&, 
or )& and a { at the start.
+     */
+    private static final String NO_RAW_FORM = "No RAW form can keep this value 
whole: RAW(...) ends at a ) followed by"
+                                              + " &, and RAW{...} ends at a } 
followed by & (and RAW{{ is the start of a"
+                                              + " property placeholder).";
+
     public static List<String> validateYamlEndpoints(String content, 
CamelCatalog catalog) {
         List<String> errors = new ArrayList<>();
         String[] lines = content.split("\n", -1);
@@ -199,7 +206,11 @@ final class EndpointChecks {
                         if (colonPos > 0) {
                             String key = unquote(paramTrimmed.substring(0, 
colonPos).trim());
                             String val = 
unquote(stripComment(paramTrimmed.substring(colonPos + 1).trim()));
-                            val = wholeValue(errors, catalog, uri.substring(0, 
uri.indexOf(':')), key, val, k);
+                            val = wholeValue(errors, catalog, uri.substring(0, 
uri.indexOf(':')), mapKey, key, val, k);
+                            if (val == null) {
+                                // the value is cut, which is reported, and 
the rest of it is not another option
+                                continue;
+                            }
                             if (mapKey != null) {
                                 // headers: with foo: bar under it is the 
entry foo of the headers map option
                                 key = mapKey + "." + key;
@@ -231,41 +242,112 @@ final class EndpointChecks {
     }
 
     /**
-     * The value of an option under parameters: as the runtime reads it whole. 
The YAML DSL adds the parameters to the
-     * uri as they are written, so an & in a value starts a new option: 
filterFile: "${file:name} contains 'R&D'" is
-     * read as filterFile=${file:name} contains 'R and an option D', and the 
route fails to start (CAMEL-26591). That is
-     * said with the fix, RAW(...), which Camel keeps as it is, and the value 
is returned in RAW(...), so that the
-     * checks of the uri see the real options and values. A secret option is 
in RAW(...) already (the YAML DSL puts it
-     * there), and a path option goes in the path, where an & is a character 
like any other.
+     * The value of an option under parameters: as the runtime reads it. Since 
CAMEL-26594 the YAML DSL keeps a value
+     * with an & whole: it puts the value in RAW(...), or in RAW{...} when the 
value has )&, as it does for a secret
+     * option. So filterFile: "${file:name} contains 'R&D'" is accepted, and 
the value is returned in that RAW form, so
+     * that the checks of the uri see the real options and values. A path 
option goes in the path, where an & is a
+     * character like any other.
+     * <p/>
+     * The YAML DSL adds some values to the uri as they are, and there an & 
still starts a new option, so the value is
+     * cut (CAMEL-26591): a value of a map option, a value that starts with # 
(a reference), and a value that no RAW
+     * form can keep whole. That is reported with what to write.
+     *
+     * @param  mapKey the map option that the value is an entry of, or null 
for an option
+     * @return        the value as the checks of the uri see it, or null to 
leave the option out of the uri: a value
+     *                that is cut and that no RAW form can keep whole (the cut 
is reported)
      */
-    static String wholeValue(List<String> errors, CamelCatalog catalog, String 
scheme, String key, String value, int lineIdx) {
+    static String wholeValue(
+            List<String> errors, CamelCatalog catalog, String scheme, String 
mapKey, String key, String value, int lineIdx) {
         if (value.indexOf('&') < 0 || value.startsWith("RAW(") || 
value.startsWith("RAW{")) {
             return value;
         }
-        // RAW(...) ends at a ) followed by &, RAW{...} at a } followed by &
-        String raw = !value.contains(")&") ? "RAW(" + value + ")" : 
!value.contains("}&") ? "RAW{" + value + "}" : null;
-        if (raw == null) {
-            return value;
+        // a value that is cut is reported, and returned in RAW (or left out 
of the uri when no RAW form can keep it
+        // whole), so that the other checks do not take the rest of it as 
another option
+        String raw = rawForm(value);
+        String cut = key + "=" + value.substring(0, value.indexOf('&'));
+        if (mapKey != null) {
+            errors.add(cutValue(lineIdx, scheme, key + " of " + mapKey,
+                    "The YAML DSL adds the values of a map option to the uri 
as they are.", cut,
+                    raw != null ? writeInRaw(key, raw, "") : NO_RAW_FORM));
+            return raw;
         }
-        boolean keptWhole = false;
+        boolean secret = false;
+        boolean path = false;
         try {
             var model = catalog.componentModel(scheme);
             if (model != null) {
-                keptWhole = model.getEndpointOptions().stream().anyMatch(
-                        o -> o.getName().equals(key) && (o.isSecret() || 
"path".equals(o.getKind())));
+                for (var o : model.getEndpointOptions()) {
+                    if (o.getName().equals(key)) {
+                        secret = o.isSecret();
+                        path = "path".equals(o.getKind());
+                    }
+                }
             }
         } catch (Exception e) {
-            // a component the catalog cannot read: the value is said to be 
cut, as the runtime cuts it
+            // a component the catalog cannot read: the value is checked as 
the value of an option
+        }
+        if (path) {
+            return raw != null ? raw : value;
+        }
+        if (value.startsWith("#")) {
+            String why = "The YAML DSL keeps a value with an & whole, but it 
adds a value that starts with # (a reference)"
+                         + " to the uri as it is.";
+            errors.add(cutValue(lineIdx, scheme, key, why, cut,
+                    raw != null ? writeInRaw(key, raw, ", and the reference 
still works") : NO_RAW_FORM));
+            return raw;
+        }
+        if (secret) {
+            // the YAML DSL puts a secret option in RAW(...), also when the 
value has )&
+            if (!value.contains(")&")) {
+                return "RAW(" + value + ")";
+            }
+            errors.add(cutValue(lineIdx, scheme, key,
+                    "The YAML DSL puts a secret option in RAW(...), and 
RAW(...) ends at a ) followed by &.",
+                    key + "=" + value.substring(0, value.indexOf(")&")), 
useProperty(key, null)));
+            return raw;
         }
-        if (!keptWhole) {
-            errors.add(linePrefix(lineIdx) + scheme + ": " + key + " has an & 
in its value. The YAML DSL adds the"
-                       + " parameters to the uri as they are, and an & starts 
a new option, so Camel reads " + key + "="
-                       + value.substring(0, value.indexOf('&')) + " and takes 
the rest as another option. Write the"
-                       + " value in RAW(...), which Camel keeps as it is: " + 
key + ": " + YamlLines.quoted(raw));
+        if (raw == null) {
+            errors.add(cutValue(lineIdx, scheme, key, NO_RAW_FORM + " So the 
YAML DSL adds the value to the uri as it is.",
+                    cut, useProperty(key, value)));
         }
         return raw;
     }
 
+    private static String cutValue(int lineIdx, String scheme, String option, 
String why, String cut, String fix) {
+        return linePrefix(lineIdx) + scheme + ": " + option + " has an & in 
its value. " + why + " An & starts a new"
+               + " option, so Camel reads " + cut + " and takes the rest as 
another option. " + fix;
+    }
+
+    /**
+     * The value in RAW(...), or in RAW{...} when the value has )& which would 
end RAW(...) too soon, as the YAML DSL
+     * puts it (YamlSupport), or null when no RAW form can keep the value 
whole: it has both )& and }&, or it has )& and
+     * starts with { (RAW{{ is the start of a property placeholder).
+     */
+    static String rawForm(String value) {
+        // RAW(...) ends at a ) followed by &, RAW{...} at a } followed by &
+        if (!value.contains(")&")) {
+            return "RAW(" + value + ")";
+        } else if (!value.contains("}&") && !value.startsWith("{")) {
+            return "RAW{" + value + "}";
+        }
+        return null;
+    }
+
+    private static String writeInRaw(String key, String raw, String note) {
+        return "Write the value in RAW(...), which Camel keeps as it is" + 
note + ": " + key + ": " + YamlLines.quoted(raw);
+    }
+
+    /**
+     * The fix for a value that no RAW form can keep whole: a property, which 
Camel reads as it is (the value of a
+     * secret option is not repeated).
+     */
+    private static String useProperty(String key, String value) {
+        return "Put the value in a property and refer to it with #property: " 
+ key + ": \"#property:" + key + "\", "
+               + (value != null
+                       ? "with " + key + "=" + value + " in 
application.properties"
+                       : "and set " + key + " in application.properties");
+    }
+
     /**
      * The line of the key (such as parameters:) of the same mapping as the 
line at idx that comes before it: the same
      * indent, up to the line that starts the mapping, or -1.
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorEndpointTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorEndpointTest.java
index c02118d172ed..f66e165a0690 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorEndpointTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorEndpointTest.java
@@ -509,10 +509,10 @@ class SourceValidatorEndpointTest {
     }
 
     @Test
-    void anAmpersandInAParameterValueSaysToWriteTheValueInRaw() {
-        // CAMEL-26591: the YAML DSL adds the parameters to the uri as they 
are, so the & cuts the value: the route fails
-        // to start on filterFile=${file:name} contains 'R. The check said 
"Unknown option 'D''", and a Simple syntax
-        // error on the cut value, without the cause or the fix
+    void anAmpersandInAParameterValueIsAccepted() {
+        // CAMEL-26594: the YAML DSL keeps a value with an & whole (in RAW), 
so filterFile: "${file:name} contains 'R&D'"
+        // runs, where the & cut the value before (CAMEL-26591). So does a 
secret option, and a path option, where an & is
+        // a character like any other
         String yaml = """
                 - route:
                     from:
@@ -526,28 +526,10 @@ class SourceValidatorEndpointTest {
                     from:
                       uri: file
                       parameters:
-                        directoryName: orders
+                        directoryName: R&D
                         filterFile: "${file:size} > 1000 && ${file:name} ends 
with '.csv'"
                       steps:
                         - log: "${file:name}"
-                """;
-        List<String> msgs = SourceValidator.validateYamlEndpoints(yaml, 
catalog);
-        assertThat(msgs).hasSize(2);
-        assertThat(msgs.get(0)).isEqualTo("Line 5: file: filterFile has an & 
in its value. The YAML DSL adds the"
-                                          + " parameters to the uri as they 
are, and an & starts a new option, so Camel"
-                                          + " reads filterFile=${file:name} 
contains 'R and takes the rest as another"
-                                          + " option. Write the value in 
RAW(...), which Camel keeps as it is:"
-                                          + " filterFile: \"RAW(${file:name} 
contains 'R&D')\"");
-        assertThat(msgs.get(1)).startsWith("Line 14: file: filterFile has an & 
in its value.")
-                .contains("Camel reads filterFile=${file:size} > 1000  and 
takes the rest as another option")
-                .endsWith("filterFile: \"RAW(${file:size} > 1000 && 
${file:name} ends with '.csv')\"");
-
-        // the fix the message gives is accepted, and so is a secret option, 
which the YAML DSL puts in RAW(...) itself
-        String fixed = yaml.replace("\"${file:name} contains 'R&D'\"", 
"\"RAW(${file:name} contains 'R&D')\"")
-                .replace("\"${file:size} > 1000 && ${file:name} ends with 
'.csv'\"",
-                        "\"RAW(${file:size} > 1000 && ${file:name} ends with 
'.csv')\"");
-        assertThat(SourceValidator.validateYamlEndpoints(fixed, 
catalog)).isEmpty();
-        assertThat(SourceValidator.validateYamlEndpoints("""
                 - route:
                     from:
                       uri: sftp:localhost:2222/inbox
@@ -556,7 +538,102 @@ class SourceValidatorEndpointTest {
                         password: "s3cr&t"
                       steps:
                         - log: "${file:name}"
-                """, catalog)).isEmpty();
+                - route:
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - to:
+                            uri: log:audit
+                            parameters:
+                              marker: "f(x)&g(y)"
+                """;
+        assertThat(SourceValidator.validateYamlEndpoints(yaml, 
catalog)).isEmpty();
+        // the value is checked whole, as the runtime reads it: a mistake in 
it is reported with the whole value
+        String wrong = yaml.replace("${file:name} contains 'R&D'", 
"${file:noext} contains 'R&D'");
+        assertThat(SourceValidator.validateYamlEndpoints(wrong, 
catalog)).satisfiesExactly(
+                m -> assertThat(m).startsWith("Line 5: file: 
filterFile=${file:noext} contains 'R&D' has a Simple syntax"
+                                              + " error: Unknown file language 
syntax: noext"));
+    }
+
+    @Test
+    void anAmpersandIsReportedWhereTheYamlDslStillCutsTheValue() {
+        // CAMEL-26594: the YAML DSL adds a value of a map option, a value 
that starts with # and a value that no RAW form
+        // can keep whole to the uri as they are, so there the & still cuts 
the value. A secret option is put in RAW(...)
+        // only, which ends at )&
+        String yaml = """
+                - route:
+                    from:
+                      uri: once
+                      parameters:
+                        name: hello
+                        headers:
+                          dept: "R&D"
+                      steps:
+                        - log: "${body}"
+                - route:
+                    from:
+                      uri: file:inbox
+                      parameters:
+                        filter: "#my&Filter"
+                      steps:
+                        - log: "${file:name}"
+                - route:
+                    from:
+                      uri: timer:tick
+                      steps:
+                        - to:
+                            uri: log:audit
+                            parameters:
+                              marker: "f(x)&g{y}&z"
+                        - to:
+                            uri: log:audit2
+                            parameters:
+                              marker: "{x})&y"
+                - route:
+                    from:
+                      uri: sftp:localhost:2222/inbox
+                      parameters:
+                        username: admin
+                        password: "s3c)&t"
+                      steps:
+                        - log: "${file:name}"
+                """;
+        String noRawForm = " No RAW form can keep this value whole: RAW(...) 
ends at a ) followed by &, and RAW{...} ends"
+                           + " at a } followed by & (and RAW{{ is the start of 
a property placeholder). So the YAML DSL"
+                           + " adds the value to the uri as it is.";
+        List<String> msgs = SourceValidator.validateYamlEndpoints(yaml, 
catalog);
+        assertThat(msgs).hasSize(5);
+        assertThat(msgs.get(0)).isEqualTo("Line 7: once: dept of headers has 
an & in its value. The YAML DSL adds the"
+                                          + " values of a map option to the 
uri as they are. An & starts a new option, so"
+                                          + " Camel reads dept=R and takes the 
rest as another option. Write the value in"
+                                          + " RAW(...), which Camel keeps as 
it is: dept: \"RAW(R&D)\"");
+        assertThat(msgs.get(1)).isEqualTo("Line 14: file: filter has an & in 
its value. The YAML DSL keeps a value with"
+                                          + " an & whole, but it adds a value 
that starts with # (a reference) to the uri"
+                                          + " as it is. An & starts a new 
option, so Camel reads filter=#my and takes the"
+                                          + " rest as another option. Write 
the value in RAW(...), which Camel keeps as it"
+                                          + " is, and the reference still 
works: filter: \"RAW(#my&Filter)\"");
+        assertThat(msgs.get(2)).isEqualTo("Line 24: log: marker has an & in 
its value." + noRawForm
+                                          + " An & starts a new option, so 
Camel reads marker=f(x) and takes the rest as"
+                                          + " another option. Put the value in 
a property and refer to it with #property:"
+                                          + " marker: \"#property:marker\", 
with marker=f(x)&g{y}&z in"
+                                          + " application.properties");
+        assertThat(msgs.get(3)).isEqualTo("Line 28: log: marker has an & in 
its value." + noRawForm
+                                          + " An & starts a new option, so 
Camel reads marker={x}) and takes the rest as"
+                                          + " another option. Put the value in 
a property and refer to it with #property:"
+                                          + " marker: \"#property:marker\", 
with marker={x})&y in application.properties");
+        assertThat(msgs.get(4)).isEqualTo("Line 34: sftp: password has an & in 
its value. The YAML DSL puts a secret"
+                                          + " option in RAW(...), and RAW(...) 
ends at a ) followed by &. An & starts a new"
+                                          + " option, so Camel reads 
password=s3c and takes the rest as another option. Put"
+                                          + " the value in a property and 
refer to it with #property: password:"
+                                          + " \"#property:password\", and set 
password in application.properties");
+
+        // the fixes the messages give are accepted
+        String fixed = yaml.replace("dept: \"R&D\"", "dept: \"RAW(R&D)\"")
+                .replace("\"#my&Filter\"", "\"RAW(#my&Filter)\"")
+                .replace("\"f(x)&g{y}&z\"", "\"#property:marker\"")
+                .replace("\"{x})&y\"", "\"#property:marker\"")
+                .replace("\"s3c)&t\"", "\"#property:password\"");
+        assertThat(SourceValidator.validateYamlEndpoints(fixed, 
catalog)).isEmpty();
     }
 
     @Test
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
index 378ef82cbb52..cd6fdddf7dfd 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
@@ -21,6 +21,9 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
 import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
@@ -101,7 +104,7 @@ public final class YamlSupport {
                     // if the uri is expressed as simple scheme, then we can 
use the
                     // discovered EndpointUriFactory to build the uri
                     //
-                    answer = factory.buildUri(scheme, parameters, false);
+                    answer = buildUri(factory, scheme, parameters);
                 } else {
                     //
                     // otherwise we have to compose it but we can still 
leverage the
@@ -119,6 +122,8 @@ public final class YamlSupport {
                             }
                         }
                     }
+                    // keep a value with & whole (a secret option is in RAW 
already)
+                    options.replaceAll((key, value) -> rawValue(value));
 
                     // flatten multiValue map parameters, where the map 
parameter is written
                     Map<String, String> prefixes = 
factory.multiValuePrefixes();
@@ -139,7 +144,7 @@ public final class YamlSupport {
                     answer += "?" + URISupport.createQueryString(flat, false);
                 }
             } else {
-                answer += "?" + URISupport.createQueryString(parameters, 
false);
+                answer += "?" + createQueryString(parameters);
             }
         } catch (URISyntaxException e) {
             throw new InvalidEndpointException(node, "Error creating query", 
e);
@@ -148,6 +153,71 @@ public final class YamlSupport {
         return answer;
     }
 
+    /**
+     * Creates the query of an endpoint uri from the parameters, not encoded 
and in the order they are written. A value
+     * with & is put in RAW to keep it whole.
+     */
+    public static String createQueryString(Map<String, Object> parameters) {
+        Map<String, Object> options = new LinkedHashMap<>(parameters);
+        options.replaceAll((key, value) -> rawValue(value));
+        return URISupport.createQueryString(options, false);
+    }
+
+    /**
+     * Builds the uri with the factory, which puts the path parameters in the 
path and the other parameters in the
+     * query. A value with & is put in RAW to keep it whole in the query. In 
the path an & does no harm, and RAW would
+     * become part of the value, so a parameter that the factory puts in the 
path is built again as it is written.
+     */
+    private static String buildUri(EndpointUriFactory factory, String scheme, 
Map<String, Object> parameters)
+            throws URISyntaxException {
+        // in the same order: as written, or sorted when the parameters have 
no order (as the factory does)
+        Map<String, Object> options
+                = parameters instanceof LinkedHashMap ? new 
LinkedHashMap<>(parameters) : new TreeMap<>(parameters);
+        // the factory puts a secret option in RAW itself
+        Set<String> secrets = factory.secretPropertyNames();
+        options.replaceAll((key, value) -> secrets.contains(key) ? value : 
rawValue(value));
+        String answer = factory.buildUri(scheme, options, false);
+
+        boolean path = false;
+        for (Map.Entry<String, Object> option : options.entrySet()) {
+            Object value = parameters.get(option.getKey());
+            if (!Objects.equals(option.getValue(), value) && 
!isInQuery(answer, option.getKey(), option.getValue())) {
+                option.setValue(value);
+                path = true;
+            }
+        }
+        return path ? factory.buildUri(scheme, options, false) : answer;
+    }
+
+    /**
+     * Whether the option is in the query of the uri, written as the factory 
writes it.
+     */
+    private static boolean isInQuery(String uri, String key, Object value) {
+        String option = URISupport.createQueryString(Map.of(key, value), 
false);
+        return uri.contains("?" + option) || uri.contains("&" + option);
+    }
+
+    /**
+     * The value in RAW when it is a text with &, as the & would end the value 
in the query of the uri. This is
+     * RAW(value), or RAW{value} when the value has )& which would end 
RAW(value) too soon.
+     * <p/>
+     * Other values are returned as they are, and so is a bean reference 
(#name), a value in RAW already, and a value
+     * that no RAW form can keep whole: it has both )& and }&, or it has )& 
and starts with { (RAW{{ is the start of a
+     * property placeholder).
+     */
+    private static Object rawValue(Object value) {
+        if (value instanceof String s && s.indexOf('&') != -1 && 
!s.startsWith("#") && !s.startsWith("RAW(")
+                && !s.startsWith("RAW{")) {
+            // a RAW value ends at the first closing bracket that is followed 
by & or the end of the uri
+            if (!s.contains(")&")) {
+                return "RAW(" + s + ")";
+            } else if (!s.contains("}&") && !s.startsWith("{")) {
+                return "RAW{" + s + "}";
+            }
+        }
+        return value;
+    }
+
     public static Node setProperty(Node node, String key, Object value) {
         node.setProperty(key, value);
 
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
index 04821dac494c..51ac84a1eb64 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
@@ -21,11 +21,11 @@ import java.util.Map;
 import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerBase;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
+import org.apache.camel.dsl.yaml.common.YamlSupport;
 import org.apache.camel.dsl.yaml.common.exception.UnsupportedFieldException;
 import org.apache.camel.model.KameletDefinition;
 import org.apache.camel.spi.annotations.YamlProperty;
 import org.apache.camel.spi.annotations.YamlType;
-import org.apache.camel.util.URISupport;
 import org.snakeyaml.engine.v2.nodes.MappingNode;
 import org.snakeyaml.engine.v2.nodes.Node;
 import org.snakeyaml.engine.v2.nodes.NodeTuple;
@@ -96,7 +96,7 @@ public class KameletDeserializer extends 
YamlDeserializerBase<KameletDefinition>
         }
 
         if (parameters != null) {
-            name += "?" + URISupport.createQueryString(parameters, false);
+            name += "?" + YamlSupport.createQueryString(parameters);
         }
 
         target.setName(name);
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml
index 718f4a4e93f3..3ce920313f8f 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/pom.xml
@@ -122,6 +122,11 @@
             <artifactId>camel-log</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-file</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-telegram</artifactId>
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc
index b5af1c7c832a..56d7f9d26463 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/docs/yaml-dsl.adoc
@@ -320,6 +320,33 @@ To define an endpoint with the YAML dsl you have two 
options:
               authorizationToken: "XXX"
 ----
 
+=== Values with an & in parameters
+
+*Available as of Camel 4.24*
+
+A value under `parameters` is added to the query of the endpoint uri. When the 
value has an `&`, Camel puts it in
+`RAW(...)`, as it does for a secret option, so the `&` does not end the value. 
For example a file filter:
+
+[source,yaml]
+----
+- route:
+    from:
+      uri: "file:inbox"
+      parameters:
+        filterFile: "${file:name} contains 'R&D' && ${file:size} > 0"
+      steps:
+        - to:
+            uri: "log:rd"
+----
+
+The value is then taken as it is written, so a `+` in it stays a `+`. In a 
value without an `&`, a `+` is read as a
+space, as in a uri. Camel does not change a value that starts with `#` (a bean 
reference), a value in `RAW(...)` or
+`RAW{...}` already, and a path parameter, such as `directoryName` when the 
`uri` is only `file`.
+
+NOTE: Camel sees the `&` only when it is written in the YAML as the value of 
an option. When it comes from a property
+placeholder, or is in a value of a map option (see below), write the value in 
RAW yourself, such as
+`+RAW({{filter}})+`.
+
 === Map values for parameters
 
 *Available as of Camel 4.15*
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/ParametersAmpersandTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/ParametersAmpersandTest.java
new file mode 100644
index 000000000000..e245181273ac
--- /dev/null
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/ParametersAmpersandTest.java
@@ -0,0 +1,382 @@
+/*
+ * 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.dsl.yaml;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.file.FileEndpoint;
+import org.apache.camel.component.file.GenericFileFilter;
+import org.apache.camel.component.log.LogEndpoint;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dsl.yaml.support.YamlTestSupport;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.model.PollDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.SwitchDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.WireTapDefinition;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.yaml.LwModelToYAMLDumper;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * CAMEL-26594: a value under parameters: with an & is kept whole in the 
endpoint uri, as it is put in RAW (as a secret
+ * option is). Before, the value was cut at the &.
+ */
+class ParametersAmpersandTest extends YamlTestSupport {
+
+    private static final String DIR = "target/data/ParametersAmpersandTest";
+
+    @Override
+    public void doSetup() throws Exception {
+        FileUtil.removeDir(new File(DIR));
+    }
+
+    @Test
+    void fileFilterWithAmpersand() throws Exception {
+        files(DIR + "/in", "R&D-plan.txt", "other.txt");
+        loadRoutes("""
+                - from:
+                    uri: file:target/data/ParametersAmpersandTest/in
+                    parameters:
+                      filterFile: "${file:name} contains 'R&D'"
+                      noop: true
+                      initialDelay: 0
+                      delay: 10
+                    steps:
+                      - to: mock:result
+                """);
+
+        
assertThat(fromUri()).isEqualTo("file:target/data/ParametersAmpersandTest/in"
+                                        + "?filterFile=RAW(${file:name} 
contains 'R&D')&noop=true&initialDelay=0&delay=10");
+        assertConsumed("R&D-plan.txt");
+    }
+
+    @Test
+    void fileFilterWithAndAndWhenTheUriIsTheScheme() throws Exception {
+        files(DIR + "/in", "R&D-plan.txt", "Report.csv", "other.txt");
+        loadRoutes("""
+                - from:
+                    uri: file
+                    parameters:
+                      directoryName: target/data/ParametersAmpersandTest/in
+                      filterFile: "${file:name} contains 'R' && ${file:name} 
ends with '.txt'"
+                      noop: true
+                      initialDelay: 0
+                      delay: 10
+                    steps:
+                      - to: mock:result
+                """);
+
+        assertConsumed("R&D-plan.txt");
+    }
+
+    @Test
+    void pathParameterWithAmpersandIsNotInRaw() throws Exception {
+        files(DIR + "/R&D", "R&D-plan.txt", "other.txt");
+        loadRoutes("""
+                - from:
+                    uri: file
+                    parameters:
+                      directoryName: target/data/ParametersAmpersandTest/R&D
+                      filterFile: "${file:name} contains 'R&D'"
+                      noop: true
+                      initialDelay: 0
+                      delay: 10
+                    steps:
+                      - to: mock:result
+                """);
+
+        // an & does no harm in the path, and RAW would be taken as part of 
the directory name
+        
assertThat(fromUri()).startsWith("file:target/data/ParametersAmpersandTest/R&D?filterFile=RAW(");
+        assertConsumed("R&D-plan.txt");
+    }
+
+    @Test
+    void kameletParameterWithAmpersand() throws Exception {
+        // a Kamelet is lenient, so before the value was cut at the & with no 
error, and the Kamelet got R
+        assertKamelet("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - to:
+                          uri: kamelet:greet
+                          parameters:
+                            message: "R&D"
+                      - to: mock:result
+                """);
+    }
+
+    @Test
+    void kameletEipParameterWithAmpersand() throws Exception {
+        assertKamelet("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - kamelet:
+                          name: greet
+                          parameters:
+                            message: "R&D"
+                      - to: mock:result
+                """);
+    }
+
+    @Test
+    void plusIsReadAsBeforeInAValueWithoutAmpersand() throws Exception {
+        loadRoutes("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - to:
+                          uri: file:target/data/ParametersAmpersandTest/out
+                          parameters:
+                            include: "R&D+.*"
+                            exclude: "draft+copy"
+                """);
+        context.start();
+
+        
assertThat(toUri(0)).isEqualTo("file:target/data/ParametersAmpersandTest/out?include=RAW(R&D+.*)&exclude=draft+copy");
+        FileEndpoint file = endpoint(FileEndpoint.class);
+        // a value in RAW is taken as it is written
+        assertThat(file.getInclude()).isEqualTo("R&D+.*");
+        // in a value without & a + is a space, as before (such as in a cron 
expression written with +)
+        assertThat(file.getExclude()).isEqualTo("draft copy");
+    }
+
+    @Test
+    void placeholderInValueWithAmpersand() throws Exception {
+        context.getPropertiesComponent().addInitialProperty("team", "Ops");
+        context.getPropertiesComponent().addInitialProperty("dept", "R&D");
+        loadRoutes("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - to:
+                          uri: log:foo
+                          parameters:
+                            marker: "{{team}} & {{dept}}"
+                """);
+        context.start();
+
+        // the placeholders are resolved in RAW, so an & in the value of a 
placeholder is kept as well
+        assertThat(toUri(0)).isEqualTo("log:foo?marker=RAW({{team}} & 
{{dept}})");
+        assertThat(endpoint(LogEndpoint.class).getMarker()).isEqualTo("Ops & 
R&D");
+    }
+
+    @Test
+    void beanReferenceIsKept() throws Exception {
+        GenericFileFilter<File> filter = file -> true;
+        context.getRegistry().bind("myFilter", filter);
+        loadRoutes("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - to:
+                          uri: file:target/data/ParametersAmpersandTest/out
+                          parameters:
+                            filter: "#myFilter"
+                            include: "R&D.*"
+                """);
+        context.start();
+
+        
assertThat(toUri(0)).isEqualTo("file:target/data/ParametersAmpersandTest/out?filter=#myFilter&include=RAW(R&D.*)");
+        FileEndpoint file = endpoint(FileEndpoint.class);
+        assertThat(file.getFilter()).isSameAs(filter);
+        assertThat(file.getInclude()).isEqualTo("R&D.*");
+    }
+
+    @Test
+    void valueInRawIsKept() throws Exception {
+        loadRoutes("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - to:
+                          uri: file:target/data/ParametersAmpersandTest/out
+                          parameters:
+                            include: "RAW(R&D.*)"
+                            exclude: "RAW{draft&copy}"
+                            antInclude: "**/R&D/**"
+                            schedulerProperties:
+                              team: "RAW(R&D)"
+                """);
+        context.start();
+
+        
assertThat(toUri(0)).isEqualTo("file:target/data/ParametersAmpersandTest/out"
+                                       + 
"?include=RAW(R&D.*)&exclude=RAW{draft&copy}&antInclude=RAW(**/R&D/**)"
+                                       + "&scheduler.team=RAW(R&D)");
+        FileEndpoint file = endpoint(FileEndpoint.class);
+        assertThat(file.getInclude()).isEqualTo("R&D.*");
+        assertThat(file.getExclude()).isEqualTo("draft&copy");
+        assertThat(file.getAntInclude()).isEqualTo("**/R&D/**");
+        // a value of a map option is added as it is, so an & in it must be in 
RAW as written
+        assertThat(file.getSchedulerProperties()).containsEntry("team", "R&D");
+    }
+
+    @Test
+    void toDWithHeaderAndAmpersand() throws Exception {
+        loadRoutes("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - toD:
+                          uri: file:target/data/ParametersAmpersandTest/out
+                          parameters:
+                            fileName: "${header.dept} & ${header.team}.txt"
+                """);
+        context.start();
+        context.createProducerTemplate().sendBodyAndHeaders("direct:start", 
"plan", Map.of("dept", "R&D", "team", "Ops"));
+
+        // Simple is evaluated in RAW, and the & from the header is kept as 
well
+        assertThat(Path.of(DIR, "out", "R&D & Ops.txt")).hasContent("plan");
+    }
+
+    @Test
+    void rawForm() throws Exception {
+        loadRoutes("""
+                - from:
+                    uri: direct:start
+                    steps:
+                      - to:
+                          uri: log:a
+                          parameters:
+                            marker: "f(x) && g(y)"
+                      - to:
+                          uri: log:b
+                          parameters:
+                            marker: "f(x)&g(y)"
+                      - to:
+                          uri: log:c
+                          parameters:
+                            marker: "{x})&y"
+                      - to:
+                          uri: log:d
+                          parameters:
+                            marker: "(x)&{y}&z"
+                """);
+
+        // RAW(value) can have a ) that is not followed by &
+        assertThat(toUri(0)).isEqualTo("log:a?marker=RAW(f(x) && g(y))");
+        assertThat(context.getEndpoint(toUri(0), 
LogEndpoint.class).getMarker()).isEqualTo("f(x) && g(y)");
+        // )& would end RAW(value) too soon, so it is RAW{value}
+        assertThat(toUri(1)).isEqualTo("log:b?marker=RAW{f(x)&g(y)}");
+        assertThat(context.getEndpoint(toUri(1), 
LogEndpoint.class).getMarker()).isEqualTo("f(x)&g(y)");
+        // no RAW form can keep these values whole, so they are as before:
+        // RAW{{ is the start of a property placeholder, and both )& and }& 
would end the value too soon
+        assertThat(toUri(2)).isEqualTo("log:c?marker={x})&y");
+        assertThat(toUri(3)).isEqualTo("log:d?marker=(x)&{y}&z");
+    }
+
+    @Test
+    void everyEndpointWithParametersAndDumpRoundTrip() throws Exception {
+        loadRoutes("""
+                - route:
+                    id: rd
+                    from:
+                      uri: direct:start
+                      steps:
+                        - wireTap:
+                            uri: log:tap
+                            parameters:
+                              marker: "R&D"
+                        - poll:
+                            uri: file:target/data/ParametersAmpersandTest/in
+                            parameters:
+                              include: "R&D.*"
+                        - switch:
+                            selector:
+                              header:
+                                expression: dept
+                            case:
+                              - value: rd
+                                uri: log:rd
+                                parameters:
+                                  marker: "R&D"
+                            otherwise:
+                              uri: log
+                              parameters:
+                                loggerName: other
+                                marker: "R&D"
+                """);
+
+        RouteDefinition route = context.getRouteDefinition("rd");
+        assertUris(route);
+
+        // the dump has the value in RAW, so it is loaded as the same uri, 
which is not put in RAW again
+        String yaml = new LwModelToYAMLDumper().dumpModelAsYaml(context, 
route, false, true, false, false);
+        try (DefaultCamelContext restored = new DefaultCamelContext()) {
+            
PluginHelper.getRoutesLoader(restored).loadRoutes(ResourceHelper.fromString("rd.yaml",
 yaml));
+            assertUris(restored.getRouteDefinition("rd"));
+        }
+    }
+
+    private static void assertUris(RouteDefinition route) {
+        assertThat(((WireTapDefinition<?>) 
route.getOutputs().get(0)).getUri()).isEqualTo("log:tap?marker=RAW(R&D)");
+        assertThat(((PollDefinition) 
route.getOutputs().get(1)).getEndpointUri())
+                
.isEqualTo("file:target/data/ParametersAmpersandTest/in?include=RAW(R&D.*)");
+        SwitchDefinition sw = (SwitchDefinition) route.getOutputs().get(2);
+        
assertThat(sw.getCases().get(0).getUri()).isEqualTo("log:rd?marker=RAW(R&D)");
+        
assertThat(sw.getOtherwise().getUri()).isEqualTo("log:other?marker=RAW(R&D)");
+    }
+
+    private static void files(String dir, String... names) throws Exception {
+        Files.createDirectories(Path.of(dir));
+        for (String name : names) {
+            Files.writeString(Path.of(dir, name), name);
+        }
+    }
+
+    private String fromUri() {
+        return 
context.getRouteDefinitions().get(0).getInput().getEndpointUri();
+    }
+
+    private String toUri(int index) {
+        return ((ToDefinition) 
context.getRouteDefinitions().get(0).getOutputs().get(index)).getEndpointUri();
+    }
+
+    private <T extends Endpoint> T endpoint(Class<T> type) {
+        return 
context.getEndpoints().stream().filter(type::isInstance).map(type::cast).findFirst().orElseThrow();
+    }
+
+    private void assertKamelet(String route) throws Exception {
+        addTemplate("greet", t -> 
t.from("kamelet:source").setBody().constant("{{message}}"));
+        loadRoutes(route);
+
+        withMock("mock:result", mock -> mock.expectedBodiesReceived("R&D"));
+        context.start();
+        withTemplate(t -> t.to("direct:start").withBody("hello").send());
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    private void assertConsumed(String... names) throws Exception {
+        MockEndpoint mock = withMock("mock:result",
+                m -> 
m.expectedHeaderValuesReceivedInAnyOrder(Exchange.FILE_NAME, (Object[]) names));
+        // wait a little to see that no other file is consumed
+        mock.setAssertPeriod(500);
+        context.start();
+        mock.assertIsSatisfied();
+    }
+}

Reply via email to