Receiving multiple files using Http Endpoint in Mule - html

I have the following html, which uploads multiple files to the URL http://localhost:5000/intake:
<form method="post" action="http://localhost:5000/intake" enctype="multipart/form-data" >
<input name="filesToUpload[]" id="filesToUpload" type="file" multiple />
<input type="submit" value="Send now" >
</form>
But in Mule, I always receive only one file.
This is my mule config:
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="5000" doc:name="HTTP Listener Configuration"/>
<file:connector name="File" autoDelete="true" streaming="true" validateConnections="true" doc:name="File"/>
<flow name="simpletestFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/intake" doc:name="HTTP" allowedMethods="POST" responseStreamingMode="NEVER"/>
<foreach collection="#[message.inboundAttachments]" doc:name="For Each">
<file:outbound-endpoint path="C:/Users/U595036/AnypointStudio/Production/upload/src/main/wsdl" outputPattern="#[key]" connector-ref="File" responseTimeout="10000" doc:name="File"/>
</foreach>
</flow>
The #[message.inboundAttachments] always has only one file in it, even if the browser sends many.

Mule can handle only one file at a time(A thread per record),In your case you can upload your files to a folder and through ftp you can process the flow.

Related

Send email with smtp using gmail

I try to send an email using gmail and the email configuration and I have looked at the threads and I still have the same problem please someone help me, thank you. the mistake is
Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=smtp://user%40gmail.com:<password>#smtp.gmail.com, connector=GmailSmtpConnector
<?xml version="1.0" encoding="UTF-8"?>
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081" doc:name="HTTP Listener Configuration"/>
<smtp:gmail-connector name="Gmail" bccAddresses="envio#gmail.com" validateConnections="true" doc:name="Gmail" contentType="text/plain" fromAddress="user#mail.com"/>
<flow name="mandaremailFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/enviar" doc:name="HTTP"/>
<set-payload value="todo va bien" doc:name="Set Payload"/>
<smtp:outbound-endpoint host="smtp.gmail.com" user="user#gmail.com" password="contrasena" to="envio#gmail.com" from="user#gmail.com" subject="hola amigo" responseTimeout="10000" doc:name="SMTP" connector-ref="Gmail"/>
</flow>
</mule>
I have modified your code as follows:
<http:listener-config name="HTTP_Listener_Configuration" host="localhost" port="8081" doc:name="HTTP Listener Configuration"/>
<smtp:gmail-connector name="Gmail" validateConnections="true" doc:name="Gmail" contentType="text/plain" />
<flow name="mandaremailFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/enviar" doc:name="HTTP"/>
<set-payload value="todo va bien" doc:name="Set Payload"/>
<smtp:outbound-endpoint host="smtp.gmail.com" user="user#gmail.com" password="contrasena" to="envio#gmail.com" from="user#gmail.com" subject="hola amigo" responseTimeout="10000" doc:name="SMTP" connector-ref="Gmail" port="587"/>
</flow>
I tried with my gmail credentials and it worked fine. I added the port here and removed unwanted data from Global gmail connector.
Also make sure you have given access to your Gmail to send emails from other 3rd party applications

MULE ESB results from database as JSON array

I am using MULE ESB and have a flow which is designed to pull all the results out of the Mysql Database and place all the results in one JSON file. However I am gettign the results as separate JSON files, not one JSON file (which is the desired outcome)
Here is my config file
<context:property-placeholder location="classpath:mysql.properties,classpath:smtp.properties" />
<smtp:connector name="emailConnector" fromAddress="${smtp.from}" subject="${smtp.subject}" doc:name="SMTP" validateConnections="true"/>
<jdbc-ee:connector name="jdbcConnector" dataSource-ref="MySQL_Data_Source" validateConnections="false" queryTimeout="10" pollingFrequency="10000" doc:name="JDBC">
<jdbc-ee:query key="Users" value="SELECT * FROM test ORDER BY id ASC"></jdbc-ee:query>
</jdbc-ee:connector>
<jdbc-ee:mysql-data-source name="MySQL_Data_Source" user="${mysql.user}" password="${mysql.password}" url="${mysql.url}" transactionIsolation="UNSPECIFIED" doc:name="MySQL Data Source"></jdbc-ee:mysql-data-source>
<flow name="flows1Flow1" >
<jdbc-ee:inbound-endpoint queryKey="Users" connector-ref="jdbcConnector" doc:name="JDBC"></jdbc-ee:inbound-endpoint>
<json:object-to-json-transformer doc:name="Object to JSON"/>
<file:outbound-endpoint path="C:\Users\IEUser\Desktop\New folder" doc:name="File" responseTimeout="10000"></file:outbound-endpoint>
</flow>
What version of Mule are you using? the jdbc connector you are using is deprecated in 3.5+. I was able to get the result you are expecting using the config below in 3.7.1:
<db:mysql-config name="MySQL_Configuration" host="localhost"
port="" user="" database="test" pass="" doc:name="MySQL Configuration" />
<flow name="flows1Flow1">
<poll doc:name="Poll">
<db:select config-ref="MySQL_Configuration" doc:name="Database">
<db:parameterized-query><![CDATA[SELECT * FROM test.people]]></db:parameterized-query>
</db:select>
</poll>
<json:object-to-json-transformer
doc:name="Object to JSON" />
<logger level="ERROR" message="#[payload]" doc:name="Logger" />
<file:outbound-endpoint path="./people"
doc:name="File" responseTimeout="10000" />
</flow>
HTH

Uploading file to Mule (http connector) from a HTML page

I am trying to upload an XML file from a HTML page to Mule-3.5 (CE). In Mule, I am unable to retrieve the contents of the file. I am attaching the HTML and the Mule configuration xml. I hope someone could help me through this.
<html>
<body>
<form action="http://localhost:8081" method="post" enctype="text/xml" >
INVOIC IDOC File:<input type="file" name="uploadedFile" size="40" accept=".xml" />
<input type="submit" name="Submit" id="button" value="Send" />
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.5.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd">
<http:connector name="HTTP_HTTPS" enableCookies="true" cookieSpec="netscape" validateConnections="true" sendBufferSize="0" receiveBufferSize="0" receiveBacklog="0" clientSoTimeout="10000" serverSoTimeout="10000" socketSoLinger="0" doc:name="HTTP-HTTPS">
<reconnect/>
</http:connector>
<flow name="httpconnectorFlow1" doc:name="httpconnectorFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" connector-ref="HTTP_HTTPS"/>
<echo-component doc:name="Echo"/>
</flow>
</mule>
The Mule script is just a test for HTTP connector. I am searching ways to extract the contents of the file uploaded.
You could use this to get things working. The thing that I have changed in the HTML is the enctype and the name of the file input.
<html>
<body>
<form action="http://localhost:8081" method="post" enctype="multipart/form-data" >
INVOIC IDOC File:<input type="file" name="payload" size="40" accept=".xml" />
<input type="submit" name="Submit" id="button" value="Send" />
</form>
</body>
</html>
for the Mule part you can use the HttpMultipartMuleMessageFactory for the HTTP connector. This lets you receive multipart/form data. Since the file input was named payload it will be the payload om the mule message, it will be a streaming payload.
Below is a sample mule flow for receiving the xml in mule and logging the payload. I use a simple object-to-string transformer to read the stream.
<http:connector name="HTTP" doc:name="HTTP">
<service-overrides messageFactory="org.mule.transport.http.HttpMultipartMuleMessageFactory" />
</http:connector>
<flow name="http-xml-receive-flow" doc:name="http-xml-receive-flow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP"/>
<object-to-string-transformer doc:name="Object to String"/>
<logger message="#[message.payload]" doc:name="Logger" level="INFO"/>
</flow>
If you plan to include other form inputs they will be available as inboundAttachments on the mule message.

Mule Proxy Service can't find definition in namespace

I've set up a few proxy services in mule, but still learning. For some reason this flow doesn't work when the namespace and service name should be correct. Anybody see my error?
Thanks for the time
<flow name="UPCFlow1" doc:name="UPCFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="4040" path="upc" doc:name="HTTP"/>
<cxf:proxy-service namespace="http://searchupc.com/" service="GetProduct" payload="envelope" wsdlLocation="http://www.searchupc.com/service/UPCSearch.asmx?WSDL" doc:name="SOAP" port="UPCSearchSoap"/>
<http:outbound-endpoint address="http://www.searchupc.com/supc/service/UPCSearch.asmx"
exchange-pattern="request-response" doc:name="HTTP"/>
</flow>
This is from the stack trace
INFO 2012-10-12 11:06:44,739 [main] org.mule.module.launcher.application.DefaultMuleApplication: App 'upc' never started, nothing to dispose of
Exception in thread "main" org.mule.module.launcher.DeploymentInitException: ServiceConstructionException: Could not find definition for service {http://searchupc.com/}GetProduct.
There is an issue in your configuration: the service name is "UPCSearch" not "GetProduct".
This works:
<flow name="UPCFlow1" doc:name="UPCFlow1">
<http:inbound-endpoint exchange-pattern="request-response"
host="localhost" port="4040" path="upc" doc:name="HTTP" />
<cxf:proxy-service namespace="http://searchupc.com/"
service="UPCSearch" payload="envelope"
wsdlLocation="http://www.searchupc.com/service/UPCSearch.asmx?WSDL"
doc:name="SOAP" port="UPCSearchSoap" />
<http:outbound-endpoint
address="http://www.searchupc.com/supc/service/UPCSearch.asmx"
exchange-pattern="request-response" doc:name="HTTP" />
</flow>

Execute action after all split messages have been processed

I have a Mule 3.3.0 flow which splits a file into records. I need to execute an action (stored procedure) AFTER ALL records have finished processing.
The problem is that sometimes the action gets executed before all records have been processed by Mule. I think this is due to the fact that Mule process stuff in parallel, which is great, so sometimes the final action gets called too early.
If I set the flow as synchronous things appear to work, but I'm not taking advantage of parallel execution.
I think I could also use a Foreach scope (haven't tried) but I guess that stuff will still not be parallelized.
Is there a way to "wait" until all records finish processing?
I'm attaching a very simple flow which exhibits this behaviour. If you run it you will see that the loggers don't print stuff in order. Actually, the "DONE" message gets logged before the rest.
The flow processes a simple csv file auntil it matches a field with value "end". There is a choice component which loggs "DONE" when such field is found. The rest of the fields simply get logged.
Any help will be greatly appreciated.
Flow:
Flow xml
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm" 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:spring="http://www.springframework.org/schema/beans" version="CE-3.3.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.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/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
<file:connector name="inputFileConnector" autoDelete="true"
streaming="false" validateConnections="true" doc:name="File" fileAge="60000"
readFromDirectory="#{systemProperties['user.home']}" />
<flow name="flow1" doc:name="flow1" processingStrategy="synchronous">
<file:inbound-endpoint path="#{systemProperties['user.home']}"
responseTimeout="10000" doc:name="Input File" fileAge="100"
connector-ref="inputFileConnector">
<file:filename-regex-filter pattern="input.csv"
caseSensitive="false" />
</file:inbound-endpoint>
<byte-array-to-string-transformer
doc:name="Byte Array to String" />
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy">
<scripting:text><![CDATA[return payload.split('\n');]]></scripting:text>
</scripting:script>
</scripting:component>
<collection-splitter doc:name="Collection Splitter" />
<choice doc:name="Choice">
<when expression="#[groovy:payload != 'end']">
<processor-chain>
<logger message="." level="INFO" doc:name="Process"/>
<vm:outbound-endpoint path="toFlow2" doc:name="VM"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="|||| DONE" level="INFO" doc:name="DONE"/>
</processor-chain>
</otherwise>
</choice>
</flow>
<flow name="flow2" doc:name="flow2" >
<vm:inbound-endpoint path="toFlow2" doc:name="VM"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy">
<scripting:text><![CDATA[return payload.split(',');]]></scripting:text>
</scripting:script>
</scripting:component>
<collection-splitter doc:name="Collection Splitter" />
<logger message="|||||| #[payload]" level="INFO" doc:name="Logger"/>
<vm:outbound-endpoint path="toFlow3" doc:name="VM"/>
</flow>
One option is to use a collection-aggregator to act as an accumulator, blocking the final flow action until all the messages have been processed. The trick is that the collection-splitters will set up a correlation group size that is only good for either the number of lines in the file or the number of columns in the file. But we want to accumulate until all columns of all lines have been processed. The solution consists in computing first this value (ie total number of expected messages) and overriding whatever correlation group size had been calculated the collection-splitters with the total value.
Here is how I've done this (you'll note that I replaced all Groovy snippets with more Mule-3-esque MEL expressions):
<file:connector name="inputFileConnector" autoDelete="true"
streaming="false" validateConnections="true" fileAge="60000"
readFromDirectory="#{systemProperties['user.home']}" />
<flow name="flow1" processingStrategy="synchronous">
<file:inbound-endpoint path="#{systemProperties['user.home']}"
responseTimeout="10000" fileAge="100"
connector-ref="inputFileConnector">
<file:filename-regex-filter pattern="input.csv"
caseSensitive="false" />
</file:inbound-endpoint>
<byte-array-to-string-transformer />
<set-session-variable variableName="expectedMessageCount"
value="#[org.mule.util.StringUtils.countMatches(message.payload, '\n') + org.mule.util.StringUtils.countMatches(message.payload, ',') - 1]" />
<expression-transformer expression="#[message.payload.split('\n')]" />
<collection-splitter enableCorrelation="IF_NOT_SET" />
<set-property propertyName="MULE_CORRELATION_GROUP_SIZE"
value="#[sessionVars.expectedMessageCount]" />
<choice>
<when expression="#[message.payload != 'end']">
<processor-chain>
<logger message="." level="INFO" />
<vm:outbound-endpoint path="toFlow2" />
</processor-chain>
</when>
<otherwise>
<processor-chain>
<logger message="|||| END" level="INFO" />
</processor-chain>
</otherwise>
</choice>
</flow>
<flow name="flow2">
<vm:inbound-endpoint path="toFlow2"/>
<expression-transformer expression="#[message.payload.split(',')]" />
<collection-splitter />
<set-property propertyName="MULE_CORRELATION_GROUP_SIZE"
value="#[sessionVars.expectedMessageCount]" />
<logger message="|||||| #[message.payload]" level="INFO"/>
<vm:outbound-endpoint path="toFinalizer" />
<vm:outbound-endpoint path="toFlow3" />
</flow>
<flow name="finalizer">
<vm:inbound-endpoint path="toFinalizer" />
<collection-aggregator />
<logger message="|||| DONE" level="INFO" />
</flow>
NB. Alternatively, if using a collection-aggregator is an issue because it uses too much memory, you could use an expression component to decrement sessionVars.expectedMessageCount and filter to let a message hit the final message processor when the counter is back to 0.