This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 76147eb6cc Implement RuntimePropertiesProvider for Quarkus to show app 
properties in dev console
76147eb6cc is described below

commit 76147eb6cc8a9bb12c752311e5db7b349de1698c
Author: James Netherton <[email protected]>
AuthorDate: Fri Aug 14 15:27:13 2026 +0100

    Implement RuntimePropertiesProvider for Quarkus to show app properties in 
dev console
    
    Fixes #8825
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
---
 .../console/deployment/ConsoleProcessor.java       | 20 ++++--
 .../console/ConsoleEnabledWithDevProfileTest.java  | 50 +++++++++++++++
 .../component/console/CamelConsoleRecorder.java    | 11 +++-
 .../console/QuarkusPropertiesDevConsole.java       | 56 +++++++++++++++++
 .../console/QuarkusRuntimePropertiesProvider.java  | 71 ++++++++++++++++++++++
 .../src/main/resources/application.properties      |  3 +-
 .../quarkus/component/console/it/ConsoleTest.java  | 24 ++++++++
 7 files changed, 227 insertions(+), 8 deletions(-)

diff --git 
a/extensions-jvm/console/deployment/src/main/java/org/apache/camel/quarkus/component/console/deployment/ConsoleProcessor.java
 
b/extensions-jvm/console/deployment/src/main/java/org/apache/camel/quarkus/component/console/deployment/ConsoleProcessor.java
index 29f388d540..d4ba375c26 100644
--- 
a/extensions-jvm/console/deployment/src/main/java/org/apache/camel/quarkus/component/console/deployment/ConsoleProcessor.java
+++ 
b/extensions-jvm/console/deployment/src/main/java/org/apache/camel/quarkus/component/console/deployment/ConsoleProcessor.java
@@ -36,6 +36,8 @@ import 
org.apache.camel.quarkus.component.console.CamelConsoleConfig;
 import org.apache.camel.quarkus.component.console.CamelConsoleRecorder;
 import org.apache.camel.quarkus.core.JvmOnlyRecorder;
 import org.apache.camel.quarkus.core.deployment.spi.CamelContextBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBeanBuildItem;
+import org.apache.camel.spi.RuntimePropertiesProvider;
 import org.eclipse.microprofile.config.ConfigProvider;
 import org.jboss.logging.Logger;
 
@@ -49,6 +51,15 @@ class ConsoleProcessor {
         return new FeatureBuildItem(FEATURE);
     }
 
+    @BuildStep
+    @Record(ExecutionTime.RUNTIME_INIT)
+    CamelRuntimeBeanBuildItem 
registerRuntimePropertiesProvider(CamelConsoleRecorder recorder) {
+        return new CamelRuntimeBeanBuildItem(
+                "quarkusRuntimePropertiesProvider",
+                RuntimePropertiesProvider.class.getName(),
+                recorder.createRuntimePropertiesProvider());
+    }
+
     @BuildStep
     @Record(ExecutionTime.STATIC_INIT)
     void initDevConsoleRegistry(
@@ -101,13 +112,14 @@ class ConsoleProcessor {
     }
 
     static final class CamelConsoleEnabled implements BooleanSupplier {
-        CamelConsoleConfig config;
+        CamelConsoleConfig camelConsoleConfig;
 
         @Override
         public boolean getAsBoolean() {
-            return config.enabled() || ConfigProvider.getConfig()
-                    .getOptionalValue("camel.main.dev-console-enabled", 
Boolean.class)
-                    .orElse(false);
+            var config = ConfigProvider.getConfig();
+            return camelConsoleConfig.enabled()
+                    || 
config.getOptionalValue("camel.main.dev-console-enabled", 
Boolean.class).orElse(false)
+                    || 
"dev".equals(config.getOptionalValue("camel.main.profile", 
String.class).orElse(null));
         }
     }
 }
diff --git 
a/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java
 
b/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java
new file mode 100644
index 0000000000..d67763bc82
--- /dev/null
+++ 
b/extensions-jvm/console/deployment/src/test/java/org/apache/camel/quarkus/component/console/ConsoleEnabledWithDevProfileTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.quarkus.component.console;
+
+import io.quarkus.test.QuarkusUnitTest;
+import jakarta.inject.Inject;
+import org.apache.camel.CamelContext;
+import org.apache.camel.console.DevConsoleRegistry;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class ConsoleEnabledWithDevProfileTest {
+    @RegisterExtension
+    static final QuarkusUnitTest CONFIG = new QuarkusUnitTest()
+            .withEmptyApplication()
+            .overrideConfigKey("camel.main.profile", "dev");
+
+    @Inject
+    CamelContext context;
+
+    @Test
+    void devConsoleRegistryLoaded() {
+        DevConsoleRegistry registry = 
context.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class);
+        assertNotNull(registry);
+        assertTrue(registry.getConsole("properties").isPresent());
+    }
+
+    @Test
+    void propertiesConsoleIsQuarkusOverride() {
+        DevConsoleRegistry registry = 
context.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class);
+        assertTrue(registry.getConsole("properties").get() instanceof 
QuarkusPropertiesDevConsole);
+    }
+}
diff --git 
a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
 
b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
index f88ff78be7..8c9f86ac09 100644
--- 
a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
+++ 
b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/CamelConsoleRecorder.java
@@ -50,10 +50,15 @@ public class CamelConsoleRecorder {
     }
 
     public void initDevConsoleRegistry(RuntimeValue<CamelContext> 
camelContextRuntimeValue) {
-        camelContextRuntimeValue.getValue()
+        DevConsoleRegistry registry = camelContextRuntimeValue.getValue()
                 .getCamelContextExtension()
-                .getContextPlugin(DevConsoleRegistry.class)
-                .loadDevConsoles();
+                .getContextPlugin(DevConsoleRegistry.class);
+        registry.register(new QuarkusPropertiesDevConsole());
+        registry.loadDevConsoles();
+    }
+
+    public RuntimeValue<QuarkusRuntimePropertiesProvider> 
createRuntimePropertiesProvider() {
+        return new RuntimeValue<>(new QuarkusRuntimePropertiesProvider());
     }
 
     static final class CamelConsoleHandler implements Handler<RoutingContext> {
diff --git 
a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusPropertiesDevConsole.java
 
b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusPropertiesDevConsole.java
new file mode 100644
index 0000000000..43a79648ea
--- /dev/null
+++ 
b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusPropertiesDevConsole.java
@@ -0,0 +1,56 @@
+/*
+ * 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.quarkus.component.console;
+
+import java.util.Map;
+
+import org.apache.camel.impl.console.PropertiesDevConsole;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+
+/**
+ * Temporary override of the Camel {@link PropertiesDevConsole} that filters 
out entries originating from
+ * {@code CamelMicroProfilePropertiesSource}. Those entries duplicate the 
application properties that Quarkus already
+ * provides through the {@code RuntimePropertiesProvider} SPI and would 
otherwise appear twice in the console output.
+ */
+public class QuarkusPropertiesDevConsole extends PropertiesDevConsole {
+
+    private static final String MICRO_PROFILE_SOURCE = 
"CamelMicroProfilePropertiesSource";
+
+    @Override
+    protected JsonObject doCallJson(Map<String, Object> options) {
+        JsonObject root = super.doCallJson(options);
+        Object props = root.get("properties");
+        if (props instanceof JsonArray arr) {
+            arr.removeIf(entry -> entry instanceof JsonObject obj
+                    && obj.get("location") instanceof String loc
+                    && loc.startsWith(MICRO_PROFILE_SOURCE));
+        }
+        return root;
+    }
+
+    @Override
+    protected String doCallText(Map<String, Object> options) {
+        StringBuilder filtered = new StringBuilder();
+        for (String line : super.doCallText(options).split("\n")) {
+            if (!line.contains(MICRO_PROFILE_SOURCE)) {
+                filtered.append(line).append('\n');
+            }
+        }
+        return filtered.toString();
+    }
+}
diff --git 
a/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusRuntimePropertiesProvider.java
 
b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusRuntimePropertiesProvider.java
new file mode 100644
index 0000000000..73c7a7718f
--- /dev/null
+++ 
b/extensions-jvm/console/runtime/src/main/java/org/apache/camel/quarkus/component/console/QuarkusRuntimePropertiesProvider.java
@@ -0,0 +1,71 @@
+/*
+ * 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.quarkus.component.console;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.camel.spi.RuntimePropertiesProvider;
+import org.eclipse.microprofile.config.ConfigProvider;
+import org.eclipse.microprofile.config.spi.ConfigSource;
+
+public class QuarkusRuntimePropertiesProvider implements 
RuntimePropertiesProvider {
+
+    private volatile Collection<Property> cached;
+
+    @Override
+    public Collection<Property> getProperties() {
+        Collection<Property> result = cached;
+        if (result == null) {
+            result = loadProperties();
+            cached = result;
+        }
+        return result;
+    }
+
+    private static Collection<Property> loadProperties() {
+        Collection<Property> answer = new ArrayList<>();
+        Set<String> seen = new LinkedHashSet<>();
+
+        for (ConfigSource source : 
ConfigProvider.getConfig().getConfigSources()) {
+            String sourceName = source.getName();
+            if (!isPropertiesSource(sourceName)) {
+                continue;
+            }
+            for (String name : source.getPropertyNames()) {
+                if (seen.add(name)) {
+                    try {
+                        String value = source.getValue(name);
+                        if (value != null) {
+                            answer.add(new Property(name, value, "Quarkus"));
+                        }
+                    } catch (Exception e) {
+                        // ignore properties that cannot be resolved
+                    }
+                }
+            }
+        }
+        return List.copyOf(answer);
+    }
+
+    private static boolean isPropertiesSource(String name) {
+        return name != null && name.startsWith("PropertiesConfigSource");
+    }
+}
diff --git 
a/integration-tests-jvm/console/src/main/resources/application.properties 
b/integration-tests-jvm/console/src/main/resources/application.properties
index c467323045..27f2dba5cf 100644
--- a/integration-tests-jvm/console/src/main/resources/application.properties
+++ b/integration-tests-jvm/console/src/main/resources/application.properties
@@ -14,4 +14,5 @@
 ## See the License for the specific language governing permissions and
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
-quarkus.camel.console.enabled=true
\ No newline at end of file
+quarkus.camel.console.enabled=true
+my.test.property=hello
diff --git 
a/integration-tests-jvm/console/src/test/java/org/apache/camel/quarkus/component/console/it/ConsoleTest.java
 
b/integration-tests-jvm/console/src/test/java/org/apache/camel/quarkus/component/console/it/ConsoleTest.java
index e277a3d40d..ab1624ee27 100644
--- 
a/integration-tests-jvm/console/src/test/java/org/apache/camel/quarkus/component/console/it/ConsoleTest.java
+++ 
b/integration-tests-jvm/console/src/test/java/org/apache/camel/quarkus/component/console/it/ConsoleTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.quarkus.component.console.it;
 
+import java.util.List;
 import java.util.Map;
 
 import io.quarkus.test.junit.QuarkusTest;
@@ -65,6 +66,29 @@ class ConsoleTest {
                         "context.state", is(ServiceStatus.Started.name()));
     }
 
+    @Test
+    void propertiesConsoleFiltersCamelMicroProfileSource() {
+        JsonPath response = RestAssured.get("/q/camel/dev-console/properties")
+                .then()
+                .statusCode(200)
+                .extract()
+                .response()
+                .jsonPath();
+
+        List<Map<String, Object>> properties = 
response.getList("properties.properties");
+
+        assertTrue(properties.stream()
+                .anyMatch(p -> "my.test.property".equals(p.get("key"))
+                        && "hello".equals(p.get("value"))
+                        && "Quarkus".equals(p.get("source"))));
+
+        assertFalse(properties.stream()
+                .anyMatch(p -> {
+                    Object loc = p.get("location");
+                    return loc instanceof String s && 
s.startsWith("CamelMicroProfilePropertiesSource");
+                }));
+    }
+
     @Test
     void invokeInvalidConsole() {
         RestAssured.get("/q/camel/dev-console/foo")

Reply via email to