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

Federico Mariani updated CAMEL-24093:
-------------------------------------
    Attachment: FileIdempotentReadLockPreMoveRollbackIssueTest.java

> camel-file: idempotent read-lock strategies compute the release key from the 
> post-preMove path - keys leak and same-named files are never consumed again
> --------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24093
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24093
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-file
>    Affects Versions: 4.21.0
>            Reporter: Federico Mariani
>            Priority: Major
>              Labels: code-review
>         Attachments: FileIdempotentReadLockPreMoveRollbackIssueTest.java
>
>
> h3. Problem
> {{FileIdempotentRepositoryReadLockStrategy.asKey}} 
> (FileIdempotentRepositoryReadLockStrategy.java:278-287) - and the same 
> pattern in {{FileIdempotentChangedRepositoryReadLockStrategy}} (315-324) and 
> {{FileIdempotentRenameRepositoryReadLockStrategy}} (229-238) - uses 
> {{file.getAbsoluteFilePath()}} directly. {{acquireExclusiveReadLock}} stores 
> key = *original* absolute path; {{GenericFileRenameProcessStrategy.begin}} 
> ({{preMove}}) then renames the file and rebinds the exchange to the renamed 
> {{GenericFile}}, so release on commit/rollback computes the key from the 
> *pre-moved* path: {{remove}}/{{confirm}} target a key that was never added, 
> and the original-path key stays in the repository forever.
> h3. Failure scenario
> {{readLock=idempotent}} (or {{idempotent-changed}}/{{idempotent-rename}}) + 
> {{preMove}}: after any rollback (default {{readLockRemoveOnRollback=true}}), 
> a new file arriving later under the same original name is silently never 
> consumed ({{idempotentRepository.add()}} fails -> "Cannot acquire read lock. 
> Will skip the file"). With {{readLockRemoveOnCommit=true}}, keys accumulate 
> unbounded and same-name files are blocked too.
> h3. History
> The sibling strategies were explicitly fixed for exactly this scenario: 
> {{MarkerFileExclusiveReadLockStrategy.asReadLockKey}} and 
> {{GenericFileHelper.asExclusiveReadLockKey}} both fall back to 
> {{getCopyFromAbsoluteFilePath()}} with a comment naming preMove ("use the 
> copy from absolute path as that was the original path of the file when the 
> lock was acquired"). The idempotent trio (CAMEL-10087 era) never received 
> that handling. No test in the repo combines {{preMove}} with 
> {{readLock=idempotent*}}.
> Secondary defect in the same classes: {{releaseExclusiveReadLockOnAbort}} is 
> a no-op, so an acquire-succeeded-then-begin-threw sequence (e.g. the preMove 
> rename itself fails) also leaks the key even without a path mismatch.
> h3. Suggested fix
> Apply the {{copyFromAbsoluteFilePath}} fallback pattern in {{asKey}} of all 
> three strategies (and evaluate the expression-based key against the original 
> file, mirroring {{GenericFileHelper.asExclusiveReadLockKey}}).
> 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). Consumer with 
> {{readLock=idempotent&preMove=work/...}} and an always-failing route; asserts 
> the original-path key is removed from the repository on rollback - on current 
> main it remains (the wrong key was removed).
> ----
> _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