Skip to content

Commit ef05798

Browse files
davsclausclaude
andauthored
CAMEL-23897: Add SpringBootRuntimePropertiesProvider for PropertiesDevConsole (#1837)
* CAMEL-23897: Add SpringBootRuntimePropertiesProvider for PropertiesDevConsole Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com> * CAMEL-23897: Per-property source labels (JVM/ENV/Spring Boot) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com> --------- Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6179be8 commit ef05798

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

core/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.apache.camel.spi.CliConnectorFactory;
4848
import org.apache.camel.spi.PackageScanClassResolver;
4949
import org.apache.camel.spi.PackageScanResourceResolver;
50+
import org.apache.camel.spi.RuntimePropertiesProvider;
5051
import org.apache.camel.spi.StartupConditionStrategy;
5152
import org.apache.camel.spi.StartupStepRecorder;
5253
import org.apache.camel.spi.VariableRepository;
@@ -405,6 +406,12 @@ ConsumerTemplate consumerTemplate(CamelContext camelContext, CamelConfigurationP
405406

406407
// SpringCamelContext integration
407408

409+
@Bean
410+
@ConditionalOnMissingBean(RuntimePropertiesProvider.class)
411+
RuntimePropertiesProvider runtimePropertiesProvider(Environment env) {
412+
return new SpringBootRuntimePropertiesProvider((ConfigurableEnvironment) env);
413+
}
414+
408415
@Bean
409416
@ConditionalOnMissingBean(PropertiesParser.class)
410417
PropertiesParser propertiesParser(Environment env) {
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.camel.spring.boot;
18+
19+
import java.util.ArrayList;
20+
import java.util.Collection;
21+
import java.util.LinkedHashSet;
22+
import java.util.Set;
23+
24+
import org.apache.camel.spi.RuntimePropertiesProvider;
25+
import org.springframework.core.env.ConfigurableEnvironment;
26+
import org.springframework.core.env.EnumerablePropertySource;
27+
28+
/**
29+
* {@link RuntimePropertiesProvider} that enumerates application properties from the Spring Boot {@link
30+
* ConfigurableEnvironment}. These properties are used for display purposes only (e.g. the Properties dev console) and
31+
* do not affect Camel's placeholder resolution.
32+
* <p>
33+
* Property sources that represent environment variables, JVM system properties, and Spring Boot internals are skipped
34+
* to avoid noise — only application-level configuration is included. However, camel/spring/server/management keys from
35+
* env/sys sources are still included since they represent application configuration.
36+
*/
37+
public class SpringBootRuntimePropertiesProvider implements RuntimePropertiesProvider {
38+
39+
private static final Set<String> SKIP_SOURCES = Set.of(
40+
"systemProperties",
41+
"systemEnvironment",
42+
"configurationProperties",
43+
"random");
44+
45+
private final ConfigurableEnvironment environment;
46+
47+
public SpringBootRuntimePropertiesProvider(ConfigurableEnvironment environment) {
48+
this.environment = environment;
49+
}
50+
51+
@Override
52+
public Collection<Property> getProperties() {
53+
Collection<Property> answer = new ArrayList<>();
54+
Set<String> seen = new LinkedHashSet<>();
55+
environment.getPropertySources().forEach(ps -> {
56+
boolean skipped = SKIP_SOURCES.contains(ps.getName());
57+
String source = toSourceLabel(ps.getName());
58+
if (ps instanceof EnumerablePropertySource<?> eps) {
59+
for (String name : eps.getPropertyNames()) {
60+
if (!seen.contains(name)) {
61+
if (skipped && !isApplicationKey(name)) {
62+
continue;
63+
}
64+
seen.add(name);
65+
try {
66+
Object value = environment.getProperty(name);
67+
answer.add(new Property(name, value, source));
68+
} catch (Exception e) {
69+
// ignore properties that cannot be resolved
70+
}
71+
}
72+
}
73+
}
74+
});
75+
return answer;
76+
}
77+
78+
private static boolean isApplicationKey(String name) {
79+
String lower = name.toLowerCase();
80+
return lower.startsWith("camel.") || lower.startsWith("camel_")
81+
|| lower.startsWith("spring.") || lower.startsWith("spring_")
82+
|| lower.startsWith("server.") || lower.startsWith("server_")
83+
|| lower.startsWith("management.") || lower.startsWith("management_");
84+
}
85+
86+
private static String toSourceLabel(String sourceName) {
87+
if ("systemProperties".equals(sourceName)) {
88+
return "JVM";
89+
} else if ("systemEnvironment".equals(sourceName)) {
90+
return "ENV";
91+
} else if ("server.ports".equals(sourceName)) {
92+
return "Spring Boot";
93+
} else {
94+
return "Spring Boot";
95+
}
96+
}
97+
}

0 commit comments

Comments
 (0)