Mule File Inbound to HTTP Outbound - mule

I have a case where I need to poll a directory on my file system. Each file that is added to that directory needs to be posted to an HTTP endpoint.
The HTTP endpoint is available on "/rest/latest/file". Using postman, I've verified that the REST call works with the following settings:
POST
basic auth
form-data:
key = file
value = Selected a file from my file system (using a dialog)
My mule flow currently looks like this:
<file:connector name="File" autoDelete="true" streaming="true" validateConnections="true" moveToPattern="#[message.inboundProperties['originalFilename']].backup" moveToDirectory="src/main/resources/output" doc:name="File"/>
<flow name="importdataqualityresultsFlow1" doc:name="importdataqualityresultsFlow1">
<file:inbound-endpoint path="src/main/resources/input" responseTimeout="10000" doc:name="File"/>
<set-payload value="#[['file' :#[message.inboundAttachments['text.txt']]]]" doc:name="Set Payload"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="80" path="rest/latest/file" method="POST" user="Admin" password="admin" contentType="application/form-data" doc:name="HTTP"/>
</flow>
I can tell in my application logs that the user logs in using basic auth, after which I get a stack trace.
Any help / pointers would be greatly appreciated.

You need to create a map payload with the form fields:
<flow name="importdataqualityresultsFlow1">
<file:inbound-endpoint path="src/main/resources/input" />
<object-to-string-transformer />
<set-payload value="#[['file': message.payload]]" />
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="80" path="rest/latest/file" method="POST" user="Admin" password="admin" contentType="application/form-data" />
</flow>

Related

How to import CSV files in Anypoint studio and convert them into JSON format?

I want to use HTTP Listener in my flows, and import csv files in Anypoint studio as input and convert them into JSON. Please help me.
you can just use a transform message and convert payload to json.
as you can see i am reading a file called address.csv.
in the transform message you can simple right
and in my logger you can see that contents of file converted to json
note -------------------------------------------------
if you want to pick a file in middle of a flow with a http listener you can always use Message-Requester module
here is how the code will look like
<file:connector name="file-connector-config" autoDelete="false" streaming="true" validateConnections="true" doc:name="File" />
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" basePath="/requester" doc:name="HTTP Listener Configuration" />
<flow name="muleRequester">
<http:listener config-ref="HTTP_Listener_Configuration" path="/requester" doc:name="HTTP" />
<logger message="Invoking Mule Requester" level="INFO" doc:name="Logger" />
<mulerequester:request resource="file://src/main/resources/in/ReadME.txt?connector=file-connector-config" doc:name="Retrieve File" returnClass="java.lang.String" />
<logger message="Payload after file requester #[payload]" level="INFO" doc:name="Logger" />
</flow>
refer link --> https://dzone.com/articles/mule-reading-file-in-the-middle-of-a-flow-using-mu
Maybe I'm misunderstanding the question, but if you'd like the http listener kick off the flow, then to load the file, you'll need a groovy script.
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[return new File("C:\test.csv").getText("UTF-8");]]></scripting:script>
</scripting:component>

Using a enricher on a Mule outbound endpoint so that the message properties context is not lost

When i make a call to to soap web service using the soap component in Mule. The message properties context is lost. I understand a Mule enricher component can be used but not sure on the usage. Below you will find my test mule code
<spring:beans>
<spring:bean id="myWebServiceImpl" class="com.xxx.xxx.service.MyWebServiceImpl">
</spring:bean>
</spring:beans>
<custom-transformer class="com.xxx.xxx.service.TestTransformer" name="Java" doc:name="Java"/>
<flow name="testwebserviceFlow1" doc:name="testwebserviceFlow1">
<file:inbound-endpoint path="c:\landing" responseTimeout="10000" doc:name="File"/>
<object-to-string-transformer doc:name="Object to String"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:28081/MyWebService" responseTimeout="100000" doc:name="HTTP" >
<cxf:jaxws-client operation="helloWorld" serviceClass="com.xxx.xxx.service.MyWebService" enableMuleSoapHeaders="true" doc:name="SOAP"/>
</http:outbound-endpoint>
<transformer ref="Java" doc:name="Transformer Reference"/>
<logger level="INFO" doc:name="Logger"/>
</flow>
<flow name="MyWebServiceFlow" doc:name="MyWebServiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" address="http://localhost:28081/MyWebService?wsdl" doc:name="HTTP" responseTimeout="100000">
<cxf:jaxws-service serviceClass="com.xxx.xxx.service.MyWebService" doc:name="SOAP"/>
</http:inbound-endpoint>
<component doc:name="MyWebService">
<spring-object bean="myWebServiceImpl"/>
</component>
</flow>
Yes, you can use an enricher to preserve your original message and put the return value of the web service into a variable. It works like this:
<enricher source="#[payload]" target="#[variable:myVal]">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:28081/MyWebService" responseTimeout="100000" doc:name="HTTP" >
<cxf:jaxws-client operation="helloWorld" serviceClass="com.xxx.xxx.service.MyWebService" enableMuleSoapHeaders="true" doc:name="SOAP"/>
</http:outbound-endpoint>
</enricher>
You can then later access the variable like this:
<logger message="#[variable:myVal]" level="INFO"/>
If you just want to call the web service and ignore any return values, you can also do that asynchronously by putting the http outbound inside <async></async> tags instead of the enricher.

mule 3, How can I send response from outbound-endpoint to another endpoint

Is there a way to send the JSON response to another server as a request asynchronously (for example to monitor, etc...)
here is my mule flow
<flow name="loggingFlow1" doc:name="loggingFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="${source.http.host}" port="${source.http.port}" doc:name="HTTP" responseTimeout="10000" />
<http:outbound-endpoint exchange-pattern="request-response" method="GET" address="http://${dest.http.host}:${dest.http.port}#[header:INBOUND:http.request]" contentType="application/json" doc:name="HTTP_GET" responseTimeout="10000" />
<async processingStrategy="Asynchronous_Processing_Strategy" doc:name="Async">
<http:outbound-endpoint exchange-pattern="one-way" address="http://localhost:8080/Monitor/response" doc:name="HTTP"/>
</async>
</flow>
For any reason, it seems the InputStream produced by the first http:outbound-endpoint is read more than once.
Serializing this InputStream to a String with an object-to-string-transformer or a byte[] with an object-to-byte-array-transformer is the best option, the echo-component is a legacy one that is not very much used anymore.

Consume wsdl service using cfx:proxy-client in Mule ESB 3.3 - Could not find definition for service

I am attempting to consume a wsdl service using cfx:proxy-client in Mule ESB 3.3 but keep getting this error
org.apache.cxf.service.factory.ServiceConstructionException: Could not find definition for service {http://support.cxf.module.mule.org/}ProxyService.
at org.apache.cxf.wsdl11.WSDLServiceFactory.create(WSDLServiceFactory.java:139)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromWSDL(ReflectionServiceFactoryBean.java:383)
at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:506)
Below is my simple flow:
<flow name="spider-middleware" doc:name="spider-middleware">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="salesforce" doc:name="HTTP"/>
<cxf:proxy-client operation="getCustomerByID"
payload="body"
wsdlLocation="http://localhost:4546/eplus-ws-fake/services/EplusCustomer/v1?wsdl"
enableMuleSoapHeaders="true"
doc:name="SOAP"/>
</flow>
The service is hardcoded to return a customer for getCustomerByID(1).
Please shed some lights on how do I get around the issue?
Thanks.
I got it working but only by providing a full SOAP envelope and not just the body, ie. using payload="envelope".
Also I removed the operation and wsdlLocation attributes, which are useless for the proxy-client. I also had to add SOAPAction and Content-Type properties, otherwise the test webservice I'm using chokes on the request.
This gives (using a test service from WebServiceX.net):
<flow name="pureCxfProxyClient">
<vm:inbound-endpoint path="test.in"
exchange-pattern="request-response" />
<set-property propertyName="SOAPAction"
value="http://www.webservicex.net/getACHByZipCode" />
<set-property propertyName="Content-Type" value="text/xml" />
<http:outbound-endpoint address="http://www.webservicex.net/FedACH.asmx"
exchange-pattern="request-response" >
<cxf:proxy-client payload="envelope" />
</http:outbound-endpoint>
</flow>
Note I used a VM endpoint, which allowed me to deal with the XMLStreamReader returned by the cxf:proxy-client.
In particular, I needed to do the following:
final XMLStreamReader xsr = (XMLStreamReader) result.getPayload();
xsr.nextTag();
to avoid crazy NPEs in org.mule.module.xml.stax.ReversibleXMLStreamReader.
All in all this is pretty intense... plus the cxf:proxy-client doesn't deliver much value when used standalone. You could actually just go with:
<flow name="pureCxfProxyClient">
<vm:inbound-endpoint path="test.in"
exchange-pattern="request-response" />
<set-property propertyName="SOAPAction"
value="http://www.webservicex.net/getACHByZipCode" />
<set-property propertyName="Content-Type" value="text/xml" />
<http:outbound-endpoint address="http://www.webservicex.net/FedACH.asmx"
exchange-pattern="request-response" />
</flow>
... and be freed of the XMLStreamReader part.

Mule flow request-response issue

In this flow the HTTP inbound is configured with request-response. But I still dont get the response as it is routed to the File outbound. How do I get a response for the HTTP endpoint and also route the response to File outbound.
<flow name="helloFlow1" doc:name="helloFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9095" doc:name="HTTP"/>
<custom-transformer class="com.uk.MyTransformer" doc:name="Java"/>
<component class="com.uk.MyComponent" doc:name="Java"/>
<echo-component doc:name="Echo"/>
<file:outbound-endpoint path="C:\" outputPattern="file#[function:datestamp]" doc:name="File"/>
You don't receive a response because nothing creates one: the file:outbound-endpoint is one-way per nature and doesn't generate a response event.
Assuming you want the same content written to the file to be also returned to the caller of the HTTP endpoint, one option consists in "detaching" the writing to the file in a parallel async flow so the main flow returns its current value to the caller:
<flow name="helloFlow1" doc:name="helloFlow1">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="9095" doc:name="HTTP"/>
<custom-transformer class="com.uk.MyTransformer" doc:name="Java"/>
<component class="com.uk.MyComponent" doc:name="Java"/>
<echo-component doc:name="Echo"/>
<async>
<file:outbound-endpoint path="C:\" outputPattern="file#[function:datestamp]" doc:name="File"/>
</async>
</flow>