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 4ca15b8754ca CAMEL-23971: fix ordered properties containsKey support 
(#24541)
4ca15b8754ca is described below

commit 4ca15b8754caddefccccd27881d29699870bac27
Author: Adriano Machado <[email protected]>
AuthorDate: Thu Jul 9 04:53:00 2026 -0400

    CAMEL-23971: fix ordered properties containsKey support (#24541)
    
    * CAMEL-23971: fix ordered properties containsKey support
    
    Delegate OrderedProperties containment checks to the backing map and add 
regression coverage for containsKey, containsValue, legacy contains, and remove 
behavior. Also switch ExportCamelMain profile presence checks to containsKey so 
explicit keys are treated as set even when their value is empty.
    
    Why: BaseOrderedProperties moved storage into a LinkedHashMap but never 
overrode the Hashtable containment methods, which broke property presence 
checks in Camel Main and Camel JBang/TUI code paths.
    
    Co-authored-by: Codex <[email protected]>
    
    * CAMEL-23971: override containsKey in CamelCaseOrderedProperties for 
camelCase/dash fallback
    
    Address review feedback on PR #24541. CamelCaseOrderedProperties overrides
    get/getProperty to look up keys as-is, then dashToCamelCase, then
    camelCaseToDash. The inherited BaseOrderedProperties.containsKey only 
checked
    the exact key, so containsKey was inconsistent with the get semantics and
    ExportCamelMain's profile presence checks could miss dash-style keys such as
    camel.management.metrics-enabled.
    
    Override containsKey to apply the same fallback so it stays consistent with
    get/getProperty. Only containsKey needs this; values are never transformed, 
so
    containsValue/contains remain the plain base-class delegation.
    
    Reviewed all BaseOrderedProperties descendants: OrderedProperties (no read
    overrides) and OrderedLocationProperties (only clear/remove overrides, no 
key
    transformation on read) need no containment changes.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    
    * CAMEL-23971: read backing map directly in 
CamelCaseOrderedProperties.containsKey
    
    Mirror the get()/getProperty() pattern where the inner lookup does not
    re-acquire the lock, instead of calling super.containsKey() three times.
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
    
    ---------
    
    Co-authored-by: Codex <[email protected]>
    Co-authored-by: Claude Opus 4.8 <[email protected]>
---
 .../apache/camel/util/BaseOrderedProperties.java   | 30 ++++++++++++++++
 .../camel/util/CamelCaseOrderedProperties.java     | 15 ++++++++
 .../camel/util/CamelCaseOrderedPropertiesTest.java | 19 ++++++++++
 .../apache/camel/util/OrderedPropertiesTest.java   | 41 ++++++++++++++++++++++
 .../dsl/jbang/core/commands/ExportCamelMain.java   |  8 ++---
 5 files changed, 109 insertions(+), 4 deletions(-)

diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/BaseOrderedProperties.java
 
b/core/camel-util/src/main/java/org/apache/camel/util/BaseOrderedProperties.java
index ed2f79e89cef..92dc44fc9e7d 100644
--- 
a/core/camel-util/src/main/java/org/apache/camel/util/BaseOrderedProperties.java
+++ 
b/core/camel-util/src/main/java/org/apache/camel/util/BaseOrderedProperties.java
@@ -76,6 +76,36 @@ abstract class BaseOrderedProperties extends Properties {
         }
     }
 
+    @Override
+    public boolean containsKey(Object key) {
+        lock.lock();
+        try {
+            return map.containsKey(key);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        lock.lock();
+        try {
+            return map.containsValue(value);
+        } finally {
+            lock.unlock();
+        }
+    }
+
+    @Override
+    public boolean contains(Object value) {
+        lock.lock();
+        try {
+            return map.containsValue(value);
+        } finally {
+            lock.unlock();
+        }
+    }
+
     @Override
     public boolean isEmpty() {
         lock.lock();
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/CamelCaseOrderedProperties.java
 
b/core/camel-util/src/main/java/org/apache/camel/util/CamelCaseOrderedProperties.java
index 127f883d80b4..6b3602b249eb 100644
--- 
a/core/camel-util/src/main/java/org/apache/camel/util/CamelCaseOrderedProperties.java
+++ 
b/core/camel-util/src/main/java/org/apache/camel/util/CamelCaseOrderedProperties.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.util;
 
+import java.util.Map;
 import java.util.Properties;
 
 /**
@@ -43,6 +44,20 @@ public final class CamelCaseOrderedProperties extends 
BaseOrderedProperties {
         }
     }
 
+    @Override
+    public boolean containsKey(Object key) {
+        lock.lock();
+        try {
+            String k = key.toString();
+            Map<String, Object> m = asMap();
+            return m.containsKey(k)
+                    || m.containsKey(StringHelper.dashToCamelCase(k))
+                    || m.containsKey(StringHelper.camelCaseToDash(k));
+        } finally {
+            lock.unlock();
+        }
+    }
+
     @Override
     public String getProperty(String key) {
         String answer = super.getProperty(key);
diff --git 
a/core/camel-util/src/test/java/org/apache/camel/util/CamelCaseOrderedPropertiesTest.java
 
b/core/camel-util/src/test/java/org/apache/camel/util/CamelCaseOrderedPropertiesTest.java
index bb5d31d8569a..54605d0cac65 100644
--- 
a/core/camel-util/src/test/java/org/apache/camel/util/CamelCaseOrderedPropertiesTest.java
+++ 
b/core/camel-util/src/test/java/org/apache/camel/util/CamelCaseOrderedPropertiesTest.java
@@ -22,6 +22,8 @@ import java.util.Properties;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class CamelCaseOrderedPropertiesTest {
 
@@ -77,4 +79,21 @@ public class CamelCaseOrderedPropertiesTest {
         assertEquals("1234", 
prop.getProperty("camel.component.direct.timeout", "MyDefault"));
     }
 
+    @Test
+    public void testContainsKeyCamelCaseAndDashFallback() {
+        Properties prop = new CamelCaseOrderedProperties();
+        prop.setProperty("camel.main.stream-caching-enabled", "true");
+        prop.setProperty("camel.component.seda.queueSize", "500");
+
+        // stored as dash, looked up as dash or camelCase
+        assertTrue(prop.containsKey("camel.main.stream-caching-enabled"));
+        assertTrue(prop.containsKey("camel.main.streamCachingEnabled"));
+
+        // stored as camelCase, looked up as camelCase or dash
+        assertTrue(prop.containsKey("camel.component.seda.queueSize"));
+        assertTrue(prop.containsKey("camel.component.seda.queue-size"));
+
+        assertFalse(prop.containsKey("camel.main.unknown"));
+    }
+
 }
diff --git 
a/core/camel-util/src/test/java/org/apache/camel/util/OrderedPropertiesTest.java
 
b/core/camel-util/src/test/java/org/apache/camel/util/OrderedPropertiesTest.java
index 00c34d328703..9299f7643c42 100644
--- 
a/core/camel-util/src/test/java/org/apache/camel/util/OrderedPropertiesTest.java
+++ 
b/core/camel-util/src/test/java/org/apache/camel/util/OrderedPropertiesTest.java
@@ -22,6 +22,8 @@ import java.util.Properties;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class OrderedPropertiesTest {
 
@@ -72,4 +74,43 @@ public class OrderedPropertiesTest {
         assertEquals("1234", it.next());
     }
 
+    @Test
+    public void testContainsKey() {
+        Properties prop = new OrderedProperties();
+        prop.setProperty("foo", "bar");
+
+        assertTrue(prop.containsKey("foo"));
+        assertFalse(prop.containsKey("bar"));
+    }
+
+    @Test
+    public void testContainsValue() {
+        Properties prop = new OrderedProperties();
+        prop.setProperty("foo", "bar");
+
+        assertTrue(prop.containsValue("bar"));
+        assertFalse(prop.containsValue("foo"));
+    }
+
+    @Test
+    public void testContainsLegacy() {
+        Properties prop = new OrderedProperties();
+        prop.setProperty("foo", "bar");
+
+        assertTrue(prop.contains("bar"));
+        assertFalse(prop.contains("foo"));
+    }
+
+    @Test
+    public void testContainsKeyAfterRemove() {
+        Properties prop = new OrderedProperties();
+        prop.setProperty("foo", "bar");
+
+        assertTrue(prop.containsKey("foo"));
+
+        prop.remove("foo");
+
+        assertFalse(prop.containsKey("foo"));
+    }
+
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
index a5e1265aa2d9..4dcbc8b41f57 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
@@ -287,13 +287,13 @@ class ExportCamelMain extends Export {
             Properties prop = new CamelCaseOrderedProperties();
             RuntimeUtil.loadProperties(prop, profile);
             // if metrics is defined then include camel-micrometer-prometheus 
for camel-main runtime
-            if (prop.getProperty("camel.metrics.enabled") != null
-                    || prop.getProperty("camel.management.metricsEnabled") != 
null
-                    || prop.getProperty("camel.server.metricsEnabled") != 
null) {
+            if (prop.containsKey("camel.metrics.enabled")
+                    || prop.containsKey("camel.management.metricsEnabled")
+                    || prop.containsKey("camel.server.metricsEnabled")) {
                 answer.add("mvn:org.apache.camel:camel-micrometer-prometheus");
             }
             // if health-check is defined then include camel-health for 
camel-main runtime
-            if (prop.getProperty("camel.management.healthCheckEnabled") != 
null) {
+            if (prop.containsKey("camel.management.healthCheckEnabled")) {
                 answer.add("mvn:org.apache.camel:camel-health");
             }
         }

Reply via email to