Federico Mariani created CAMEL-26654:
----------------------------------------

             Summary: camel-azure-storage-datalake - getFile overwrites a File, 
Path or GenericFile body with the remote file
                 Key: CAMEL-26654
                 URL: https://issues.apache.org/jira/browse/CAMEL-26654
             Project: Camel
          Issue Type: Bug
          Components: camel-azure
    Affects Versions: 4.18.5, 4.23.0, 4.22.2
            Reporter: Federico Mariani


h3. Problem
The producer operation {{getFile}} decides whether to download into the message 
body with {{message.getBody(OutputStream.class)}}: 
{{components/camel-azure/camel-azure-storage-datalake/src/main/java/org/apache/camel/component/azure/storage/datalake/operations/DataLakeFileOperations.java}}
 line 72 on main (commit 7978db3d42dd). That is a type conversion, not a type 
check:
* a {{java.io.File}} or {{java.nio.file.Path}} body converts to a buffered 
output stream that truncates the file ({{IOConverter.toOutputStream(File)}} and 
{{toOutputStream(Path)}});
* a {{GenericFile}} body, which is what a {{file:}} consumer sets, converts the 
same way through the fallback of {{GenericFileConverter}}.

{{getFile}} then downloads the Data Lake file into that stream. So 
{{from("file:in").to("azure-storage-datalake:account/fs?fileName=a.txt&operation=getFile")}}
 empties the consumed local file and replaces its content with the remote file, 
instead of returning the remote file as an {{InputStream}}. The route was read 
from source; the operation itself is measured below. The component 
documentation says the download goes to "an {{OutputStream}} supplied as the 
message body" ({{azure-storage-datalake-component.adoc}} lines 419 and 425).

CAMEL-25933 fixed the same defect in camel-azure-storage-blob {{getBlob}} 
(commit 631b74151c65, main only): {{BlobOperations.java}} lines 106-108 now 
only use a body that *is* an {{OutputStream}}. That change did not touch 
camel-azure-storage-datalake. The datalake consumer is not affected, because 
its exchange body is empty when it calls {{getFile}}.

h3. How to reproduce
A unit test (measured on main) calls {{DataLakeFileOperations.getFile}} with a 
mocked {{DataLakeFileClientWrapper}}. The mock's {{downloadWithResponse}} 
writes {{"remote"}} into the stream it is given, and its {{openInputStream()}} 
returns {{"remote"}}:
{code:java}
Path local = Files.writeString(dir.resolve("consumed.txt"), "local file 
content");
exchange.getIn().setBody(FileConsumer.asGenericFile(dir.toString(), 
local.toFile(), null, false)); // or local.toFile(), or local
new DataLakeFileOperations(configuration, client).getFile(exchange);
Files.readString(local); // "remote"
{code}
||Body||Path taken by getFile||Local file afterwards||
|{{java.io.File}}|download into a {{BufferedOutputStream}} over the 
file|{{remote}}|
|{{GenericFile}} (as set by a file consumer)|download into a 
{{BufferedOutputStream}} over the file|{{remote}}|
|{{java.nio.file.Path}}|download into a {{BufferedOutputStream}} over the 
file|{{remote}}|
|control: {{ByteArrayOutputStream}}|download into that stream (expected)|n/a|
|control: no body|{{openInputStream()}}, an {{InputStream}} is returned 
(expected)|n/a|

h3. Proposed change
* Do what CAMEL-25933 did for blob: use the body only when it is an 
{{OutputStream}} ({{message.getBody() instanceof OutputStream os ? os : 
null}}). Otherwise return the {{InputStream}} from {{openInputStream}}, as for 
any other body.
* Add tests with {{File}}, {{Path}} and {{GenericFile}} bodies, plus the 
{{OutputStream}} and no-body controls.
* To save a file locally, users keep the {{downloadToFile}} operation (with 
{{fileDir}}), or send the {{InputStream}} to a {{file:}} endpoint.

h3. Impact / upgrade
* Behaviour change for routes that relied on a {{File}}, {{Path}} or 
{{GenericFile}} body being overwritten with the remote file. This needs an 
entry in the 4.24 upgrade guide, worded like the existing 
"camel-azure-storage-blob - getBlob writes only into an OutputStream body" 
entry.
* Affected: 4.18.5, 4.22.2 and 4.23.0 (the same line at each release tag). The 
line has been there since the component was created (CAMEL-15341).
* Only the producer operation {{getFile}} is affected.
* The blob fix (CAMEL-25933) is on main only. If this is backported to 4.18.x 
and 4.22.x, the blob fix probably should be too.

h3. Related
* CAMEL-25933 (631b74151c65): the same fix for camel-azure-storage-blob 
{{getBlob}}.
* CAMEL-26583: the latest change to the same {{getFile}} method (ranges on 
streaming downloads).
* CAMEL-15341: the component's creation.

_Claude Code on behalf of Federico Mariani_



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to