shashank created CAMEL-25859:
--------------------------------

             Summary: camel-mongodb-gridfs - the consumer routes a file with 
the content and headers of the newest file that has the same name, so the 
content of the older file is never routed
                 Key: CAMEL-25859
                 URL: https://issues.apache.org/jira/browse/CAMEL-25859
             Project: Camel
          Issue Type: Bug
          Components: camel-mongodb-gridfs
            Reporter: shashank
            Assignee: shashank


{{GridFsConsumer.processCollection}} (main 20cdb309f7d0, line 212) opens the 
download stream of each file the poll found by its file name:

{code:java}
GridFSDownloadStream downloadStream = 
endpoint.getGridFsBucket().openDownloadStream(file.getFilename());
file = downloadStream.getGridFSFile();
{code}

GridFS does not make file names unique: every upload with a name that already 
exists adds a file (a revision), and {{GridFSBucket.openDownloadStream(String 
filename)}} opens the newest revision of that name. The component docs say so 
too (the {{count}} operation counts the files matching a filename, {{listAll}} 
lists names with their ids). So when one poll finds two or more files with the 
same name, every exchange gets the stream of the newest one, and the headers 
({{CamelFileLength}}, {{CamelFileLastModified}}, content type, metadata) are 
taken from it as well. The older file is routed with the content of the newer 
one, its own content is never routed, and the newer content is routed twice. 
With a file attribute strategy the older file is then marked {{done}}.

When does a poll find two files with the same name: two uploads of the same 
name within one poll delay (500 ms by default); with {{PersistentTimestamp}}, 
every revision uploaded while the consumer was stopped; with the 
{{FileAttribute}} strategies, every revision not marked yet, for example all of 
them at the first start. A producer that uploads a report or an export under a 
fixed name ({{CamelFileName}} header) does exactly this.

*Fix*: open the stream by the id of the found file 
({{openDownloadStream(file.getId())}}). The query, the file attribute and the 
timestamp already work by id and upload date; only the stream was by name.

*Tests*: {{GridFsConsumerTimestampTest}} (the fake bucket of CAMEL-25607 / 
CAMEL-25711) now answers {{openDownloadStream}} as MongoDB does: by name the 
newest file of that name, by id that file. New 
{{filesWithTheSameNameAreEachRoutedWithTheirOwnContent}}, for each of the 5 
query strategies: two files named {{report.csv}} found by the same poll. On 
main all 5 fail: {{expected: <[<id of the first>, <id of the second>]> but was: 
<[<id of the second>, <id of the second>]>}}. With the fix they pass; 
camel-mongodb-gridfs unit tests: 20 run, 0 failures (the ITs need Docker and 
were not run).

*How it was found*: a review of the consumers that run their own poll loop; the 
stream opened by name next to a query and a file attribute that work by id 
stood out. Then the JUnit test above. Not run against a MongoDB server; the 
by-name behaviour is that of the documented driver API.

*Affected*: main, camel-4.23.x, camel-4.22.x, camel-4.18.x and camel-4.14.x 
(the same {{openDownloadStream(file.getFilename())}} in {{GridFsConsumer}}; 
read, not run).

_Filed with Claude Code on behalf of allthingssecurity._




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

Reply via email to