0
votes

I am polling from SFTP in mulesoft every second,fileAge is set to 0, connection pool size is 1 and autodelete is enabled. Then i save the file to the directory within a File connector which is polling ever 2 seconds and file age is 500(This is the outbound endpoint. Then the next flow starts with this same directory as File inbound endpoint and process the file. Here is polling set to every 3 seconds and autodelete is enabled.I get this error but file is processed..

java.io.IOException: The requested file does not exist (//file/7ggot1517.txt)
at org.mule.transport.sftp.SftpClient.getSize(SftpClient.java:499)
at org.mule.transport.sftp.SftpClient.retrieveFile(SftpClient.java:378)
...

Does anyone have some knowledge how to configure sftp and file connector to :

1.Read File From SFTP and delete it from SFTP

2.Process the File from local directory and delete it?

3.Get rid of that error

Thank you

2
Can you copy/paste the XML flows related to your issue? Without it its not clear enough whats steps your flow is going through ;)Pierre B.
For sure :) this is the first flow for polling from sftp <flow name="pullFromSftpFlow"> <sftp:inbound-endpoint connector-ref="SFTP" host="${ftp.host}" port="${ftp.port}" path="${ftp.path}" user="${ftp.user}" password="${ftp.password}" doc:name="SFTP" responseTimeout="10000"/> <file:outbound-endpoint path="C://SFTP" outputPattern="#[message.inboundProperties.originalFilename]" connector-ref="File2" responseTimeout="10000" doc:name="File"/> </flow>MarkyMark
This is the file2 setting <file:connector name="File2" autoDelete="false" streaming="false" validateConnections="true" doc:name="File" pollingFrequency="2000"/ and the setting of SFTP is polling frequency 1000,fileAge:0,autodelete:true,sizeCheckwaitTime:0MarkyMark
Then the next flow which source is file inbound endpoint looks like this <file:inbound-endpoint path="C://SFTP" connector-ref="File" responseTimeout="10000" encoding="US-ASCII" doc:name="File" pollingFrequency="3000" autoDelete="true"> </file:inbound-endpoint> <set-variable variableName="fileName" value="#[flowVars.originalFilename]" doc:name="Save fileName"/> <logger message="#[&quot;File obatained : &quot; +flowVars.fileName]" level="INFO" doc:name="Logger"/> and then it goes to processing of that file.. hope you can help :)MarkyMark
Thanks, you can also edit your answser to add such details, easier to read ;) So if I understand properly, your file is processed properly, but you still have this error in the log?Pierre B.

2 Answers

0
votes

Can you try the below configuration...I tried reading file from FTP to local directory ..

  1. Replace FTP with SFTP
  2. Use the little small groovy script provided in that.This should work .I just tested this and working as expected .Deleting can be done by autoDelete attribute or fileAge .Please let me know if this helps
<flow name="ftptestFlow">
    <ftp:inbound-endpoint host="hostname" port="port" path="path/filename" user="userid" password="password" responseTimeout="10000" doc:name="FTP"/>
    <set-variable variableName="fileName" value="fileName" doc:name="fileName"/>
    <scripting:component doc:name="getFile">
        <scripting:script engine="Groovy"><![CDATA[new File(flowVars.fileName).getText('UTF-8')]]></scripting:script>
    </scripting:component>
    <file:outbound-endpoint path="path" outputPattern="filename" responseTimeout="10000" doc:name="File"/>
</flow>

0
votes

Your SFTP inbound endpoint probably tries to poll the file a first time, but a second poll is started before the first one had a chance to delete file. Something like this happens:

  1. First poll - a file is found, let's read it => OK
  2. First poll - read the file and process it => OK
  3. Second poll - a file is found, let's read it => OK
  4. First poll - processing finished, delete the file => OK
  5. Second poll - read the file and process it => Error: file has been deleted

As you see a second poll detects the presence of the file before the first poll actually deletes it, but by the time it tries to read it the first poll already had the file deleted.

You can use the tempDir attribute on your SFTP inbound endpoint, it will move the file to a sub-directory of the folder where it is read before processing, ensuring subsequent polls are not triggered for the same file again. It then does something like:

  1. First poll - a file is found, move it to tempDir and let's read it => OK
  2. First poll - read the file and process it => OK
  3. Second poll - No file found (it has been moved!) => OK
  4. First poll - processing finished, delete the file => OK

Such as:

<sftp:inbound-endpoint connector-ref="SFTP" 
    tempDir="${ftp.path}/tmpPoll"
    host="${ftp.host}" 
    port="${ftp.port}" 
    path="${ftp.path}" 
    user="${ftp.user}" 
    password="${ftp.password}" doc:name="SFTP" responseTimeout="10000"/>

You also need to make sure the SFTP user can read/write the sub-dir or create it if necessary. Everything is documented here.

EDIT: and to delete your file from the local machine you can simply use a Java or Groovy component once it has been properly processed

try {
    Files.delete(filePath);
} catch (...) {

}