Read file from FTP in mule - mule

I am loading request file to FTP (below flow where loading part works perfectly fine).
I am trying to read file (which is result of request file load) from FTP server and could not find any solution. Any suggestion?
<flow name="FTP_FLOW">
<file:inbound-endpoint responseTimeout="10000" doc:name="File" path="D:\AnypointStudio\workspace\ftppoc\src\test\resources\in" pollingFrequency="10000" moveToDirectory="D:\AnypointStudio\workspace\ftppoc\src\test\resources\backup"/>
<ftp:outbound-endpoint host="hostname" port="21" responseTimeout="10000" doc:name="FTP" password="password" path="/path" user="username"/>
</flow>

The ftp connector provided by MuleSoft can write a file from within a flow or it can poll a directory (inbound connector).
When you want to read a file with given name within a flow, you can use the open source connector from here: https://github.com/rbutenuth/ftp-client-connector/

Related

Call a File Inbound Endpoint via Http endpoint - Set XML as payload and update in IBM MQ

I am designing an application flow where I have to read a file (XML File) and put the data into IBM MQ (Queue). Do I need to create an HTTP request that will trigger the File read and update queue, otherwise how do I perform this task.
Currently I am creating an HTTP Request and connecting it to WMQ but I am getting NULL data into the Queue. Basically the payload is NULL.
This is the data I read when I browse the Queue:
sr.org.mule.transport.NullPayload1.L5U���...xp
Try like this:
Whenever you use File connector at any other place than the beginning of the flow, then it becomes an outbound endpoint.
For using File as an inbound endpoint to retrieve any file, you must use it in the beginning of some flow & keep the flow in stopped state initially as:
<flow name="filePickupFlow" initialState="stopped">
<file:inbound-endpoint path="src/main/resources/input" responseTimeout="10000" doc:name="File"/>
<wmq:outbound-endpoint queue="gh" doc:name="WMQ" connector-ref="WMQ"/>
</flow>
For your case just change the path with your required file location.
Then for further calling it via http, create another flow with http endpoint & use an Expression component to start the flow containing file inbound endpoint call as :
<expression-component doc:name="Expression">
app.registry.filePickupFlow.start();
</expression-component>
Then if you wish to stop it after it completes processing, you can again use an Expression component as:
<expression-component doc:name="Expression">
Thread.sleep(5000);
app.registry.filePickupFlow.stop();
</expression-component>
Thread.sleep() is used here just to give some time gap between flow start & stop to let the flow operation complete. You can add some other thing for maintaing this time gap or set the time according to your own usage.
I guess this is what you were looking for.
Regards,
JJ
If you want to access the file component on-demand( Whenever you access the HTTP, only then File component needs to access), use Mule Requester in the place of file component which do the same work.
<mulerequester:config name="Mule_Requester" doc:name="Mule Requester"/>
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" basePath="test2" doc:name="HTTP Listener Configuration"/>
<flow name="httpFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/" doc:name="HTTP"/>
<mulerequester:request config-ref="Mule_Requester" resource="file://C:/in" doc:name="Mule Requester"/>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="**payload:*#[payload]" level="INFO" doc:name="Use WMQ here instead of Logger"/>
</flow>
Link to refer: https://github.com/mulesoft/mule-module-requester/blob/master/mulerequesterdemo/src/main/app/MuleRequesterDemo.xml
Instead of HTTP, you can also schedule job trigger using Poll component based on your requirement. Hope this helps.
You wanted to used file connector as inbound endpoint but actually using as outbound endpoint. Check your configuration xml file for file connector.
There are many ways for reading file as inbound like file connector, Poll scope or Quartz connector. You can use anyone of these as per you requirement. The simplest flow is as
<flow name="testfixedFlow">
<file:inbound-endpoint path="tmp" connector-ref="File" responseTimeout="10000" doc:name="File"/>
<wmq:outbound-endpoint queue="xyz" connector-ref="WMQ" doc:name="WMQ"/>
</flow>
But if you want to get resource in between the flow you can use Mule requester
Hope this helps.

How to attach file in Munit for functional test cases- Mule ESB

I need to do end to end (Functional Testing)testing via Munit. For that, I need to attach actual payload which is Image. How can I attach the image in Inbound message processor( Munit - Set Message, there is no option for attachment) or any other way we can achieve this.
<flow name="TestImage">
<file:inbound-endpoint path="tmp\imageUpload" responseTimeout="10000" doc:name="ImageFlow" connector-ref="fileConn" fileAge="100" pollingFrequency="500"></file:inbound-endpoint>
............. many processor..... Logic involved...
<file:outbound-endpoint path="tmp\Upload" responseTimeout="10000" doc:name="Flow" connector-ref="fileConn" fileAge="100" pollingFrequency="500"></file:outbound-endpoint>
Mule Studio Version: 5.3.1
The file inbound endpoint will by default return a input stream as payload with the content of the file you want to read.
Now MUnit disable inbound endpoints by default so to test this flow you'll have to do a flow-ref to your flow "TestImage".
In this case you can use the set message processor and load the test file you want to use in the following way:
<munit:set payload="#[getResource('test_image.jpeg').asStream()]" doc:name="Set Message"/>
This'll create a message with a payload that's an input stream for your image.
HTH.

Mule GZip Compress

Hi i am using anypoint studio 2014 release, and i need to create two flows, the first flow needs to receive a fixed width file and then compress it into a gzip file and the send it out, the second flow is suppose to get a gzip file, decompress it, and send on the fixed width file. I have not done the second flow yet but i am having a problem with the first flow when i try to compress the fixed width file this returns the file in its normal form but when i open the file it is all junk inside, please help me with this:
<flow name="cibtest" doc:name="cibtestFlow1">
<file:inbound-endpoint path="c:users\....\in" responseTimeout="10000" doc:name="File"/>
<gzip-compress-transformer/>
<file:outbound-endpoint path="c:users\....\out" responseTimeout="10000" doc:name="File"/>
</flow>
The "junk inside" is compressed data. Use a gzip decompressor to see what's inside the file.

Multiple File InBound Endpoint in the same flow

I have two directories from where i want to pick files and send it to SFTP server , but i want to send directory1 files first , if it is successful then only i need to send files from directory2 . How do achieve this processing sequence ?
In the Batch Processing documentation, you'll see an entry for error handling, which states the following (my emphasis):
From time to time, when processing a batch job, a Mule message
processor in a batch step may find itself unable to process a record.
When this occurs – perhaps because of corrupted or incomplete record
data – Mule has three options for handling a record-level error:
stop processing the entire batch, skip any remaining batch steps and push all records to the On Complete phase (where, ideally, you
have designed a report to notify you of failed records)
continue processing the batch regardless of any failed records, using filters to instruct subsequent batch steps how to handle failed
records
continue processing the batch regardless of any failed records (using filters to instruct subsequent batch steps how to handle failed
records), until the batch job accumulates a maximum number of failed
records at which point Mule pushes all records to the On Complete
phase (where, ideally, you have designed a report to notify you of
failed records)
By default, Mule's batch jobs follow the first error handling option
which halts processing as soon as Mule encounters a single
record-level error.
So, to do what you require, you need to create a batch job where directory1 is processed first, then set max-failed-records to 0.
The nicer solution I see is to use Mule Module Requester to read the second set of files to later process them. Download the jar for Studio or Mule ESB standalone from the link and write a config like this:
<mule xmlns:mulerequester="http://www.mulesoft.org/schema/mule/mulerequester"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/jersey http://www.mulesoft.org/schema/mule/jersey/current/mule-jersey.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/mulerequester http://www.mulesoft.org/schema/mule/mulerequester/current/mule-mulerequester.xsd">
<file:connector name="File1" autoDelete="true" streaming="false" validateConnections="true" doc:name="File"/>
<file:endpoint path="/temp/in2" name="File2" responseTimeout="10000" doc:name="File"/>
<flow name="main" doc:name="main">
<file:inbound-endpoint path="/temp/in1" responseTimeout="10000" doc:name="File" connector-ref="File1"/>
<mulerequester:request resource="File2" returnClass=""/>
<logger level="ERROR"/>
</flow>
</mule>
1)Create 2 flows:- Flow1 and Flow2
2)Configure both the flows with file inbound endpoint with 2 different folders .....
3)Now suppose Flow1 need to execute first and flow 2 need to execute after that, make intial state property of flow 2 as stopped ..(So the file inbound endpoint of the flow will not pick the file from the directory) ......
4)Put a flow reference in flow 1 after your execution happened so that it call flow 2 ... so it will happen sequentially
example :-
<flow name="flow1" doc:name="f1">
<file:inbound-endpoint path="C:\folder1" responseTimeout="10000" doc:name="File" />
<!-- Do your busssiness proccess -->
<!--Start the flow2 -->
<scripting:component doc:name="Script">
<scripting:script engine="groovy">
muleContext.registry.lookupFlowConstruct('flow2').start()
</scripting:script>
</scripting:component>
<!-- Now call the second flow using Flow ref -->
<flow-ref name="flow2" doc:name="Flow Reference"/>
</flow>
<flow name="flow2" doc:name="f2" initialState="stopped">
<file:inbound-endpoint path="C:\folder2" responseTimeout="10000" doc:name="File" />
<!-- Do your busssiness proccess -->
</flow>

Does Mule have the ability to simply move/rename a file?

Is there a way to simply "move/rename" a file in Mule as opposed to a copy? The flow below performs a copy, but what I really want is to simply rename the file. The file can be quite large.
<file:connector name="Global-StageToInput" fileAge="10000" autoDelete="true" pollingFrequency="30000"/>
<file:connector name="Global-FileInput" outputPattern="#[header:originalFilename]" />
<flow name="Global-MoveInputFiles">
<file:inbound-endpoint connector-ref="Global-StageToInput" path="${stage}"/>
<file:outbound-endpoint connector-ref="Global-FileInput" path="${input}"/>
</flow>
When you want to move a file from one directory to another the file aparently vanishes from the directory you are moving .
Back up of this file can be taken using the moveToDirectory in Inbound endpoint
In order to rename the backup file you can use moveToPattern in Inbound endpoint
In order to rename in the destination you can use outputPattern in Outbound endpoint
You can use the following links to have more ideas
<file:inbound-endpoint connector-ref="input" path="/tmp/input" moveToDirectory="/tmp/backup" moveToPattern="#[header:originalFilename].backup"/>
<file:outbound-endpoint connector-ref="output" path="/tmp/output" outputPattern="#[function:datestamp]-#[header:originalFilename]"/>
http://www.mulesoft.org/documentation/display/current/File+Transport+Reference
http://www.mulesoft.org/documentation-3.2/display/32X/File+Transport+Reference
http://www.mulesoft.org/connectors/file-connector
If you need only to move a file from a folder to another where you need to rename the file name.
Then use the following code
<file:inbound-endpoint connector-ref="input" path="/tmp/input"/>
<file:outbound-endpoint connector-ref="output" path="/tmp/output" outputPattern="#[function:datestamp]-#[header:originalFilename]"/>
Just only the pattern in the outbound endpoint.
Only the path in the input and output is required .Rest all is not necessary and with mix and match of the option that is there links can be used. Even the connector-ref is not required for a basic requirement