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)

Reply via email to