davsclaus commented on code in PR #27686:
URL: https://github.com/apache/camel/pull/27686#discussion_r4255125196


##########
components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java:
##########
@@ -214,11 +430,12 @@ public static RouteDefinition 
templateToRoute(RouteTemplateDefinition in, Map<St
             // (if ppid is null then it is a source kamelet)
             if (ppid != null) {
                 ProcessorDefinition<?> pro = mcc.getProcessorDefinition(ppid);
-                wrap = pro == null || 
ProcessorDefinitionHelper.shouldWrapInErrorHandler(mcc, pro, null,
-                        CamelContextHelper.parseBoolean(mcc, 
pro.getInheritErrorHandler()));
+                wrap = pro == null || 
ProcessorDefinitionHelper.shouldWrapInErrorHandler(
+                        mcc, pro, null, CamelContextHelper.parseBoolean(mcc, 
pro.getInheritErrorHandler()));

Review Comment:
   Most of the unrelated changes are gone, thanks. A few are left in 
`templateToRoute` and `extractKameletProperties`: this re-wrapped 
`shouldWrapInErrorHandler` call, the "kamelet" -> "Kamelet" comment change 
below, the blank lines added after `in.asRouteDefinition()`, after 
`def.setNodePrefixId(uuid)`, after this `if` block and around the sink `for` 
loop, the reworded "This is appended..." comment, and the blank line removed 
after `prefixBuffer.append(element).append('.')`. Please revert these as well 
so the diff only contains the feature.



##########
components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java:
##########
@@ -184,6 +205,199 @@ public static void 
extractKameletEnvironmentVariables(Map<String, Object> proper
         }
     }
 
+    /**
+     * Reads the original advanced options map stored under a single internal 
key.
+     */
+    private static Map<String, Object> extractAdvancedOptions(Map<String, 
Object> parameters, String key) {
+        Map<String, Object> options = new LinkedHashMap<>();
+        if (parameters == null) {
+            return options;
+        }
+
+        Object value = parameters.get(key);
+        if (value instanceof Map<?, ?> map) {
+            for (Map.Entry<?, ?> entry : map.entrySet()) {
+                if (entry.getKey() != null) {
+                    options.put(entry.getKey().toString(), entry.getValue());
+                }
+            }
+        }
+
+        return options;
+    }
+
+    /**
+     * Preserves the user-supplied option name. When both camelCase and 
kebab-case forms are present, the kebab-case
+     * form is kept so the same option is not appended twice.
+     */
+    private static Map<String, Object> normalizeParameterNames(Map<String, 
Object> parameters) {
+        Map<String, Object> normalized = new LinkedHashMap<>();
+        Map<String, String> seenOriginal = new HashMap<>();
+        Map<String, Boolean> seenIsCanonical = new HashMap<>();
+
+        if (parameters == null) {
+            return normalized;
+        }
+
+        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+            String originalName = entry.getKey();
+            String name = StringHelper.camelCaseToDash(originalName);
+            boolean isCanonical = originalName.equals(name);
+
+            String existingOriginal = seenOriginal.get(name);
+            if (existingOriginal == null) {
+                seenOriginal.put(name, originalName);
+                seenIsCanonical.put(name, isCanonical);
+                normalized.put(originalName, entry.getValue());
+            } else {
+                boolean existingIsCanonical = seenIsCanonical.get(name);
+                if (isCanonical && !existingIsCanonical) {
+                    normalized.remove(existingOriginal);
+                    seenOriginal.put(name, originalName);
+                    seenIsCanonical.put(name, isCanonical);
+                    normalized.put(originalName, entry.getValue());
+                }
+            }
+        }
+
+        return normalized;
+    }
+
+    /**
+     * Appends query parameters without parsing or re-encoding the endpoint 
URI. This preserves property placeholders
+     * and RAW expressions that may appear in the URI.
+     */
+    private static String appendParametersToURI(String uri, Map<String, 
Object> parameters) {
+        if (parameters == null || parameters.isEmpty()) {
+            return uri;
+        }
+
+        String result = uri;
+        StringBuilder qs = new StringBuilder();
+        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+            String name = entry.getKey();
+            String value = String.valueOf(entry.getValue());
+
+            result = removeQueryParameter(result, name);
+            qs.append(result.contains("?") || qs.length() > 0 ? "&" : "?");
+            qs.append(name).append('=').append(wrapRawIfNeeded(value));
+        }
+        result += qs;
+        return result;

Review Comment:
   This changed from `+=` to a `StringBuilder`, and the separator is now wrong 
in one case. `removeQueryParameter` returns the URI without `?` when it removes 
the last parameter. If that happens after the first option is already in `qs`, 
the result has no `?`: `log:foo?level=WARN` with `showAll=true, level=INFO` (in 
that order) becomes `log:foo&showAll=true&level=INFO`. Removing all overridden 
names first and then appending fixes it:
   
   ```suggestion
           String result = uri;
           for (String name : parameters.keySet()) {
               result = removeQueryParameter(result, name);
           }
   
           StringBuilder sb = new StringBuilder(result);
           char sep = result.indexOf('?') < 0 ? '?' : '&';
           for (Map.Entry<String, Object> entry : parameters.entrySet()) {
               sb.append(sep).append(entry.getKey()).append('=')
                       
.append(wrapRawIfNeeded(String.valueOf(entry.getValue())));
               sep = '&';
           }
           return sb.toString();
   ```
   
   A test with two `sink.*` options where the second one overrides the only 
existing parameter would cover it.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to