James Netherton created CAMEL-25919:
---------------------------------------
Summary: camel-core: DefaultDumpRoutesStrategy: setOutput with a
directory keeps the file name from a previous setOutput
Key: CAMEL-25919
URL: https://issues.apache.org/jira/browse/CAMEL-25919
Project: Camel
Issue Type: Bug
Reporter: James Netherton
h3. Summary
DefaultDumpRoutesStrategy.setOutput() does not clear a previously set output
file name when given a directory
h3. Description
{{DefaultDumpRoutesStrategy}} keeps the output location in two fields:
{{output}} (directory) and {{outputFileName}} (optional fixed file name).
{{setOutput(String)}} treats the value as a file if the last path segment
contains a dot and sets both fields. When given a directory it only updates
{{output}}, so any {{outputFileName}} from an earlier call stays in place.
{code:java}
public void setOutput(String output) {
String name = FileUtil.stripPath(output);
if (name != null && name.contains(".")) {
outputFileName = name;
this.output = FileUtil.onlyPath(output);
...
} else {
this.output = output; // outputFileName is not reset
}
}
{code}
The strategy is a context plugin shared by everything that uses the
{{CamelContext}}. So a file-style dump followed by a folder-style dump on the
same context keeps writing to the old file name:
* XML/YAML: {{resolveFileName()}} returns the stale {{outputFileName}}, so the
dump goes to {{<new folder>/<old file name>}} instead of the usual per-resource
files.
* PNG: {{doDumpRoutesDiagram()}} prefers {{outputFileName}} and calls
{{dumpRoutesToFile(..., new File(name))}}, so all routes are rendered into a
single PNG named after the old file (e.g. {{MyTest-test.xml}}) in the working
directory. Only the topology diagram reaches the requested folder.
h3. Reproducer (camel-core, verified on main)
{code:java}
package org.apache.camel.impl;
public class DumpRoutesStaleFileNameReproTest extends ContextTestSupport {
@Test
public void folderAfterFile() throws Exception {
DumpRoutesStrategy drs =
context.getCamelContextExtension().getContextPlugin(DumpRoutesStrategy.class);
drs.setInclude("*");
drs.setLog(false);
File fileDir = testDirectory().resolve("first").toFile();
File folder = testDirectory().resolve("second").toFile();
drs.setOutput(new File(fileDir, "MyTest-test.xml").getPath());
drs.dumpRoutes("xml");
drs.setOutput(folder.getPath());
drs.dumpRoutes("xml");
// fails: folder contains [MyTest-test.xml]
assertThat(folder.list()).isNotEmpty().doesNotContain("MyTest-test.xml");
}
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
from("direct:a").routeId("a").to("mock:a");
from("direct:b").routeId("b").to("mock:b");
}
};
}
}
{code}
*Actual:* {{second/}} contains {{MyTest-test.xml}}.
*Expected:* {{second/}} contains the usual auto-named dump ({{dump1.xml}}).
h3. Impact
Shows up wherever a CamelContext is reused across dumps, for example:
* camel-test-main-junit6 with both {{dumpRoute}} and {{dumpRouteDiagramFolder}}
* cached Spring Boot test contexts
* Camel Quarkus tests, where test classes share one application
Plain {{CamelTestSupport}} mostly avoids it because it usually creates a new
context per test.
Callers cannot work around it by saving and restoring the settings. There is no
getter for {{outputFileName}}, {{getOutput()}} returns only the directory, and
{{setOutput(dir)}} cannot clear the file name.
h3. Suggested fix
Reset the file name when a directory is given (verified: the reproducer passes
with this change):
{code:java}
} else {
outputFileName = null;
this.output = output;
}
{code}
{{setOutput(dir)}} would then start a fresh directory output, so callers no
longer need a getter for the file name to undo an earlier file-style dump.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)