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")