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 3ff57c15325e CAMEL-25434: camel-jbang - Show the properties file a
property comes from (#27534)
3ff57c15325e is described below
commit 3ff57c15325ea1857c25a72976476ac39729faa9
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Oct 8 08:31:00 2026 +0200
CAMEL-25434: camel-jbang - Show the properties file a property comes from
(#27534)
camel get properties showed an empty LOCATION for properties from
application.properties: the dev console reports the location, but the
CLI turned every location it had no readable name for into an empty
string. Keep such a location, the properties file, as it is.
The monitor's Configuration tab showed only the source a placeholder
was resolved from, so a property that no route used yet had an empty
SOURCE. Show the location then, and widen the column so
file:application.properties fits.
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
.../core/commands/process/ListProperties.java | 21 +++++++++--------
.../core/commands/process/ListPropertiesTest.java | 26 +++++++++++++++++++++
.../jbang/core/commands/tui/ConfigurationTab.java | 27 +++++++++++++++-------
.../commands/tui/ConfigurationTabRenderTest.java | 27 ++++++++++++++++++++++
4 files changed, 84 insertions(+), 17 deletions(-)
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
index 16ff85b34f4d..2e5680cbc80a 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/process/ListProperties.java
@@ -231,18 +231,21 @@ public class ListProperties extends ProcessWatchCommand {
}
}
- private static String sanitizeLocation(String loc) {
+ /**
+ * A readable name of where a property comes from, such as
application.properties or OS Environment Variable.
+ */
+ public static String sanitizeLocation(String loc) {
if (loc == null) {
return "";
}
- switch (loc) {
- case "initial", "override" -> loc = "camel-main";
- case "SYS" -> loc = "JVM System Property";
- case "ENV", "env" -> loc = "OS Environment Variable";
- case "arguments", "CLI" -> loc = "Command Line";
- default -> loc = "";
- }
- return loc;
+ return switch (loc) {
+ case "initial", "override" -> "camel-main";
+ case "SYS" -> "JVM System Property";
+ case "ENV", "env" -> "OS Environment Variable";
+ case "arguments", "CLI" -> "Command Line";
+ // a properties file, such as application.properties
+ default -> loc;
+ };
}
}
diff --git
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
index 8ab0232b492f..bfb7b6fffb09 100644
---
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
+++
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/process/ListPropertiesTest.java
@@ -145,6 +145,32 @@ class ListPropertiesTest extends ProcessCommandTestSupport
{
}
}
+ @Test
+ void testPropertiesFileLocationShown() throws Exception {
+ JsonObject root = new JsonObject();
+ root.put("context", contextObj());
+ root.put("properties", propertyContainer("properties",
+ property("greeting", "Hello", "Hello", false, null,
"application.properties")));
+ writeStatusFile(TEST_PID, root);
+
+ ListProperties command = new ListProperties(new
CamelJBangMain().withPrinter(printer));
+ command.sort = "pid";
+ command.jsonOutput = true;
+
+ try (MockedStatic<ProcessHandle> mocked =
mockStatic(ProcessHandle.class)) {
+ ProcessHandle ph = mockProcessHandle(TEST_PID);
+ ProcessHandle currentHandle = mockCurrentHandle();
+ mocked.when(ProcessHandle::current).thenReturn(currentHandle);
+ mocked.when(ProcessHandle::allProcesses).thenAnswer(inv ->
Stream.of(ph));
+
+ int exit = command.doCall();
+
+ assertEquals(0, exit);
+
assertTrue(printer.getOutput().contains("\"location\":\"application.properties\""),
+ "The properties file should be shown as the location");
+ }
+ }
+
private static JsonObject contextObj() {
JsonObject ctx = new JsonObject();
ctx.put("name", "myApp");
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
index f7b07bde5676..57d1cfa4b8bf 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java
@@ -43,6 +43,7 @@ import dev.tamboui.widgets.table.Cell;
import dev.tamboui.widgets.table.Row;
import dev.tamboui.widgets.table.Table;
import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.dsl.jbang.core.commands.process.ListProperties;
import org.apache.camel.dsl.jbang.core.common.CatalogLoader;
import org.apache.camel.tooling.model.BaseOptionModel;
import org.apache.camel.tooling.model.ComponentModel;
@@ -158,7 +159,7 @@ class ConfigurationTab extends AbstractTableTab {
result.sort((a, b) -> {
int cmp = switch (sort) {
case "value" -> compareStr(a.value, b.value);
- case "source" -> compareStr(a.source, b.source);
+ case "source" -> compareStr(sourceOf(a), sourceOf(b));
default -> compareCamelFirst(a, b);
};
return sortReversed ? -cmp : cmp;
@@ -166,6 +167,17 @@ class ConfigurationTab extends AbstractTableTab {
return result;
}
+ /**
+ * Where a property comes from: the source it was resolved from, or else
the location it was loaded from (a property
+ * that no placeholder has used yet has no source).
+ */
+ static String sourceOf(ConfigProperty p) {
+ if (p.source != null && !p.source.isEmpty()) {
+ return FileUtil.stripPath(p.source);
+ }
+ return ListProperties.sanitizeLocation(p.location);
+ }
+
private void renderTable(Frame frame, Rect area, List<ConfigProperty>
props) {
List<Row> rows = new ArrayList<>();
for (ConfigProperty p : props) {
@@ -173,10 +185,7 @@ class ConfigurationTab extends AbstractTableTab {
String value = p.value != null ? p.value : "";
Style valStyle = secret ? SECRET_STYLE : Style.EMPTY;
- String source = "";
- if (p.source != null && !p.source.isEmpty()) {
- source = FileUtil.stripPath(p.source);
- }
+ String source = sourceOf(p);
rows.add(Row.from(
Cell.from(Span.styled(p.key,
Style.EMPTY.fg(Theme.accent()))),
@@ -202,7 +211,8 @@ class ConfigurationTab extends AbstractTableTab {
.widths(
Constraint.percentage(35),
Constraint.fill(),
- Constraint.length(20))
+ // wide enough for file:application.properties and OS
Environment Variable
+ Constraint.length(28))
.highlightStyle(detailFocused ? Theme.selectionBg().dim() :
Theme.selectionBg())
.highlightSpacing(Table.HighlightSpacing.ALWAYS)
.block(Block.builder().borderType(BorderType.ROUNDED).borders(Borders.ALL)
@@ -274,8 +284,9 @@ class ConfigurationTab extends AbstractTableTab {
String value = prop.value != null ? prop.value : "";
boolean secret = "xxxxxx".equals(value);
addDetailField(lines, "Current value", secret ? "xxxxxx (masked)" :
value, area.width());
- if (prop.source != null && !prop.source.isEmpty()) {
- addDetailField(lines, "Source", FileUtil.stripPath(prop.source),
area.width());
+ String source = sourceOf(prop);
+ if (!source.isEmpty()) {
+ addDetailField(lines, "Source", source, area.width());
}
if (option == null) {
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
index 9e0a05b98c66..b10edea7d037 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTabRenderTest.java
@@ -26,6 +26,7 @@ import dev.tamboui.terminal.Frame;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
@@ -138,6 +139,32 @@ class ConfigurationTabRenderTest {
// ---- Helper methods ----
+ @Test
+ void sourceFallsBackToLocation() {
+ // a property that no placeholder has used yet has no source, only the
file it was loaded from
+ ConfigurationTab.ConfigProperty prop = addProperty("greeting",
"Hello", null);
+ prop.location = "application.properties";
+
+ ConfigurationTab tab = new ConfigurationTab(ctx);
+ String rendered = TuiTestHelper.renderToString(tab, 120, 20);
+
+ assertTrue(rendered.contains("application.properties"), "Should render
the location as the source");
+ }
+
+ @Test
+ void sourceOfPrefersResolvedSource() {
+ ConfigurationTab.ConfigProperty prop = new
ConfigurationTab.ConfigProperty();
+ prop.source = "file:application.properties";
+ prop.location = "initial";
+ assertEquals("file:application.properties",
ConfigurationTab.sourceOf(prop));
+
+ prop.source = null;
+ assertEquals("camel-main", ConfigurationTab.sourceOf(prop));
+
+ prop.location = null;
+ assertEquals("", ConfigurationTab.sourceOf(prop));
+ }
+
private ConfigurationTab.ConfigProperty addProperty(String key, String
value, String source) {
ConfigurationTab.ConfigProperty prop = new
ConfigurationTab.ConfigProperty();
prop.key = key;