How do I use a file inbound endpoint to process a file whose name I get from MuleClient.dispatch() as payload - mule

Below is my file inbound endpoint configuration. It is processing all .edi files available at the specified path.
<file:inbound-endpoint path="D:\test docs\in"
pollingFrequency="3000" responseTimeout="10000" doc:name="Incoming File">
<file:filename-regex-filter pattern="(.*).edi"
caseSensitive="false" />
I send an event to this endpoint from spring application as below
muleClient.dispatch("file://D:/test docs/in", inputFileName,
null);
I am passing the input file name as message1.edi. I want to restrict file inbound point to process single file whose name is sent as payload object in dispatch().
Is it possible with file inbound endpoint?
Muleclient.dispatch() is an async method. I want to pause the current thread till i get reply from dispatch(). As of now i am using thread.sleep(). Is there any better approach?

I may be missing the point :-) however I don't think the dispatch is what you want to use.
To trigger the event on the mule file listener, copy your message1.edi to the file folder file://D:/test docs/in
mule will pickup the file and process.
Alternativly, I don't think the mule file endpoint support dynamically changing the regex, if you want to dynamically change the file then trigger your flow with muleClient.dispatch("file://D:/test docs/in", inputFileName, null); and use a groovy component to read an process the file named in the trigger
def fileContent = new File("file://D:/test docs/in/" + inputFileName).text
return fileContent
Adjust according if not text files.

There is no need for an inbound endpoint. You need to use a the request method of the MuleClient to get a custom file content on demand:
muleClient.request('file://D:/test docs/in', -1);

sorry i could have posted the whole mule flow code.
Below is my mule flow:
<flow name="ediTransformationFlow" doc:name="ediTransformationFlow">
<file:inbound-endpoint path="D:\smooks\test docs\in"
pollingFrequency="3000" responseTimeout="10000" doc:name="Incoming File"
transformer-refs="SmooksTransformer" moveToDirectory="D:\smooks\test docs\history"
moveToPattern="#[header:originalFilename]">
<file:filename-regex-filter pattern="(.*).edi"
caseSensitive="false" />
</file:inbound-endpoint>
<file:outbound-endpoint path="D:\smooks\test docs\out" responseTimeout="10000"
doc:name="Outgoing File" outputPattern="#[header:originalFilename].xml"/>
</flow>
My requirement is:
From spring controller I will send .edi file name to file inbound endpoint. It will read the file from D:\smooks\test docs\in folder, transforms it to xml file.
File outbound end point places the xml file in D:\smooks\test docs\out folder.
In spring controller i should be able to read the xml file and create a dom source.
xmlDocument = builder.parse(documentRootPath + outputFileName);
Source source = new DOMSource(xmlDocument);
To request mule from spring controller i am using mule client
muleClient.dispatch("file://D:/smooks/test docs/in", inputFileName,null);
message = muleClient.request("file://D:/smooks/test docs/out",
100000);

Related

Mule email attachment extension is null

I am able to send an email attachment using SMTP connector in MULE. But when my attachment arrives in "Inbox" it comes with ".null" extension.
If I open that file in notepad my expected data is present in the file.
I am unable to figure out why the extension is coming null.
My attachment looks like this
"MyFIle-01312019_0256.null"
This is my configuration
<set-attachment attachmentName="#[sessionVars.'channel-smtp-attachment-prefix']-#[server.dateTime.format('MMddyyyy_HHmm')].#[flowVars.'channel-smtp-attachment-extension']" value="#[payload]" contentType="#[flowVars.'channel-smtp-attachment-type']" doc:name="Mail Endpoint"/>
And I set in code like this
myObj.setAttribute("channel-smtp-attachment-prefix", REPORT_NAME_PREFIX);
I tried following way
myObj.setAttribute("channel-smtp-attachment-prefix", REPORT_NAME_PREFIX + ".txt");
Then my attachment looks like this
MyFIle.txt-01312019_0256.null
I need ".txt" extension. Suggest me a way to do.

Split - transform - aggregate

I'm trying to write test application using twitter connector.
The flow is next:
Load retweets;
Here I'm getting a list of retweets and I want to transform them one by one. I'm using for-each, but earlier I used collection-splitter.
How I understand, outside foreach block I should have already transformated payload, but in this place I'm getting the same result as at the beginning.
Here is my flow:
<flow name="twits">
<http:listener config-ref="HTTP_Listener_Configuration" path="/twits" doc:name="HTTP"/>
<twitter:get-retweets statusId="111111111111" config-ref="Twitter" doc:name="Twitter"/>
<foreach>
<transformer ref="ReTwitTransformer"/>
</foreach>
<json:object-to-json-transformer doc:name="Object to JSON"/>
</flow>
So the problem is at 3 step, I can't set transformed data into message payload. I already had tried to use set-payload but without success.
The Foreach scope returns the original message after processing each element. Your transformations will not be retained.
In this case, you might try the Batch Processing module (EE) or just use a Collection Splitter (CE) as you tried previously.
Also, I noticed you're using an HTTP listener to start things off. If you actually need the collection of transformed retweets back as an HTTP response, you'll have to add a bit more:
If you use the Batch module, you'll need to pair it with a Request Reply router in order to get the collection of successful records back synchronously. Just put a Batch Execute for the Request, and a VM inbound endpoint for the Reply. Then just put a VM outbound endpoint in the Batch On Complete step.
If you use a Collection Splitter, you'll need a Collection Aggregator after the transformation occurs. You might wait until after aggregation to do the object-to-json-transformer.

mule invoke java component as array parameter

properties file:
#torun='GSD11','GSD12'
torun='GSD11'
<flow name="deleteInvoiceFlow" doc:name="deleteInvoiceFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="${hostname}" port="${port}" path="deleteInvoice" doc:name="HTTP"/>
<invoke object-ref="client" method="deleteInvoice" methodArguments="${torun}" methodArgumentTypes="java.lang.String" />
</flow>
<spring:bean id="client" name="client" class="com.util.DeleteTable"/>
Java: DeleteTable:
public String deleteInvoice(#Payload String deleteCompany) throws SQLException{
It works well for single parameter from the properties as shown above in properties file. But If i run application with below companies in properties
`torun='GSD11','GSD12'
it gives error message as
1 (java.lang.ArrayIndexOutOfBoundsException). Message payload is of type: String
How do I enable to receive parameteras array?
the Mule message's Payload is a Object. Thus allowing it to handle any kind of object.
If you check the MuleMessage interface you'll see it.
In your code above your sending whatever comes from your inbound endpoint (http) to your spring bean, and you are assuming it's going to be a string.
Now the payload can certainly change in an http inbound endpoint depending on what type of request you receive (get/post/put/etc) so be careful with that.
Going back to your question, if you're positive the payload is going to be an array you can just change the firm of your method to that. If not I'll advise you change it to object and validate what's coming and cast accordingly.
HTH
Mule docs says:
http://www.mulesoft.org/documentation/display/current/Invoke+Component+Reference
methodArguments="#[1], #[2]"
methodArgumentTypes="java.lang.Float, java.lang.Float"
but my list is random and it grows to 100s to 1000s, I don't want to put 1000s of argument types.
As a workaround solution I am loading the mule-app.propertes in java component and reading the property content.
public String deleteInvoice(){
Properties prop = new Properties();
InputStream input = DeleteTable.class.getClassLoader().getResourceAsStream("mule-app.properties");
prop.load(input);
return prop.getProperty("torun");
}

Amazon SQS Message and "Could not find a transformer to transform SimpleDataType..."

I'm using very simple flow, where I have tried to set message attribute( for SQS) in flowVars, so that it will be reflected in my SQS Queue. I have used this link https://github.com/mulesoft/sqs-connector/blob/master/src/test/resources/automation-test-flows.xml for references(In the link they referred by using flow vars). But i'm getting the error like
"Could not find a transformer to transform "SimpleDataType{type=java.lang.String,mimeType='*/*'}" to "SimpleDataType{type=java.util.Map, mimeType='*/*'}". (org.mule.api.transformer.TransformerException)"
Pleasse find my config xml
<flow name="sqsFlow1" doc:name="sqsFlow1">
<sqs:receive-messages config-ref="Amazon_SQS" doc:name="Amazon SQS (Streaming)" numberOfMessages="5" visibilityTimeout="11"/>
<set-variable variableName="setMessageAtt" value="[name:"John"]" doc:name="Variable"/>
sqs:send-message config-ref="Amazon_SQS1" doc:name="Amazon SQS" >
<sqs:message-attributes ref="#[flowVars.setMessageAtt]"/>
</sqs:send-message>
</flow>
I understand the value which I try to return as String, but it is expecting Map. Is there any way we can change the string vaue in to Map inside flow variable itself ( Via MEL). If not, how we can handle the scenario. I have tried multiple scenario , but it is not working.
Your help is required.
Thanks in advance.
In mule you can represent a Map as: #[key1 : value1, key2 : value2, . . .]
For example, with mel:
#[['title':'value','description':'value','status':'404','bit': false]]
is equivalent to
Map<String, Object>
I hope to help;

ESB MULE passing the parameters to the java method

I use MULE version 3.3.0 CE, I want to get some value from header in inbound and then pass it to a java method, in java method making some changes on passed value, finally again I pass it from java method to the outbound????
Instead of tying your Java beans to the Mule API (with Callable), you can do this using MEL only, for example with:
<invoke object-ref="yourBean"
method="yourMethod"
methodArguments="#[message.inboundProperties['inboundPropertyName']]" />
<set-property propertyName="outboundPropertyName"
value="#[payload]" />
This has the caveat that the message payload is affected by the invoke element. If this is a problem then you can go with:
<expression-component>
propVal = app.registry.yourBean.yourMethod(message.inboundProperties['inboundPropertyName']);
message.outboundProperties['outboundPropertyName'] = propVal;
</expression-component>
Make your Java component implement org.mule.api.lifecycle.Callable
In its onCall you can get the message as follows:
MuleMessage message = eventContext.getMessage();
Now you can obtain the inbound properties:
Object someProp = message.getInboundProperty("some_prop_name");
After operating over it, you place it back as an outbound property:
message.setOutboundProperty("some_prop_name", someProp);