[ 
https://issues.apache.org/jira/browse/CAMEL-24095?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Federico Mariani updated CAMEL-24095:
-------------------------------------
    Attachment: FileProducerTempFileMoveExistingNonEagerIssueTest.java

> camel-file: tempFileName + fileExist=Move + eagerDeleteTargetFile=false 
> silently overwrites the existing target instead of moving it (no Move branch 
> in handleExistingTarget)
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24095
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24095
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-file, camel-ftp
>    Affects Versions: 4.21.0
>            Reporter: Federico Mariani
>            Priority: Major
>              Labels: code-review
>         Attachments: FileProducerTempFileMoveExistingNonEagerIssueTest.java
>
>
> h3. Problem
> {{GenericFileProducer.handleExistingTarget}} 
> (GenericFileProducer.java:249-266) - the non-eager exists handler used when 
> writing via {{tempFileName}}/{{tempPrefix}} with 
> {{eagerDeleteTargetFile=false}} - covers {{Ignore}}, {{Fail}} and 
> {{Override}} but has *no Move branch*, unlike its eager twin 
> {{handleExistingTargetEager}} (line 235-237) which calls the 
> {{moveExistingFileStrategy}}. It returns false and {{renameFile(tempTarget, 
> target)}} proceeds: {{FileUtil.renameFile}} uses {{Files.move(..., 
> ATOMIC_MOVE)}} (or copy with {{REPLACE_EXISTING}} as fallback), so the 
> pre-existing target is overwritten and lost - never archived to the 
> {{moveExisting}} destination, which is the entire point of {{fileExist=Move}}.
> h3. Failure scenario
> {{to("file:out?tempFileName=inprogress-${file:name}&fileExist=Move&moveExisting=archive/&eagerDeleteTargetFile=false")}}
>  with an existing target: the old file is destroyed instead of moved to 
> {{archive/}}. This combination is deliberate usage - per the 
> {{eagerDeleteTargetFile}} javadoc, non-eager is exactly how you get "fail if 
> a file already exists at the move destination" semantics for the moveExisting 
> operation.
> h3. History
> CAMEL-15822 (235a0a5f3d15, 2020) was titled "fileExist=Move doesn't use 
> FileMoveExistingStrategy when tempFile is also configured" but patched only 
> the eager branch; the non-eager branch has lacked Move handling since the 
> logic's inception and through the 2023 helper-extraction refactor 
> (1bcab0700cd9).
> h3. Suggested fix
> Add the Move branch to {{handleExistingTarget}}, mirroring 
> {{handleExistingTargetEager}}.
> Adjacent defect in the same code path: with {{eagerDeleteTargetFile=false}}, 
> the temp file is fully written before the exists check, and the 
> {{Ignore}}-return / {{Fail}}-throw / failed-rename paths all leave the temp 
> file orphaned on disk (unbounded accumulation with date/UUID-bearing 
> {{tempFileName}} expressions).
> h3. Note for the fix
> Existing test 
> {{FileProducerMoveExistingTest.testFailOnMoveExistingFileExistsEagerDeleteFalseTempFileName}}
>  currently *asserts the buggy behavior* (it expects the pre-existing 
> move-target to keep its old content, i.e. no move happened) and will need 
> updating together with the fix.
> h3. Reproducer
> Attached failing JUnit test (place in 
> {{core/camel-core/src/test/java/org/apache/camel/component/file/}}, where the 
> file component tests live). Pre-creates the target with content OLD, produces 
> NEW through the tempFileName+Move+non-eager endpoint, and asserts the OLD 
> content was archived to {{archive/}} - on current main the archive file does 
> not exist and OLD is destroyed.
> ----
> _This issue was researched and filed by Claude Code on behalf of [~croway] 
> (GitHub: Croway), as part of a deep code review of camel-file and camel-ftp. 
> A failing JUnit reproducer is attached; it fails deterministically on current 
> main (4.22.0-SNAPSHOT)._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to