Mule flow is not triggering - mule

I am using Groovy inside Poll to check file existence at given location.
My flow is working fine, when there is a file. But If I delete that file, flow is not triggering.Below is my code
<flow name="monitor-dst-file-flow">
<poll doc:name="Poll">
<schedulers:cron-scheduler expression="0 0 23 ? * TUE-SAT"/>
<scripting:transformer doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[def endpointBuilder = muleContext.endpointFactory.getEndpointBuilder(
"sftp://${user}:${pwForGroovy}#${host}:${port}${inputpath}/?connector=SFTP")
endpointBuilder.addMessageProcessor(new org.mule.routing.MessageFilter(new org.mule.transport.file.filters.FilenameWildcardFilter('test.txt')))
def inboundEndpoint = endpointBuilder.buildInboundEndpoint()
inboundEndpoint.request(30000L)]]>
</scripting:transformer>
</poll>
<choice doc:name="Choice">
<when expression="#[message.inboundProperties.originalFilename =="test.txt"]">
<logger level="INFO" doc:name="Logger" message="File Exists..."/>
</when>
<otherwise>
<logger message="FILE EXISTS" level="ERROR" doc:name="Logger"/>
<flow-ref name="email-notification-sub-flow" doc:name="Flow Reference"/>
</otherwise>
</choice>
</flow>
Here, if there is no test.txt file, I am not able to debug Choice component.
It says -Polling of monitor-dst-file-flow returned null, the flow will not be invoked.
I am not able to identify the exact solution to run my flow. I have to handle that condition, where given file is not there.

You need to return something besides null from the poller's target for the flow to be invoked. I'd recommend doing this in a sub-flow:
<flow name="monitor-dst-file-flow">
<poll doc:name="Poll">
<schedulers:cron-scheduler expression="0 0 23 ? * TUE-SAT"/>
<flow-ref name="pollerProcessor" doc:name="pollerProcessor"/>
</poll>
<choice doc:name="Choice">
<when expression="#[payload == 'file not found']">
<logger level="INFO" doc:name="Logger" message="File Exists..."/>
</when>
<otherwise>
<logger message="FILE EXISTS" level="ERROR" doc:name="Logger"/>
<flow-ref name="email-notification-sub-flow" doc:name="Flow Reference"/>
</otherwise>
</choice>
</flow>
<sub-flow name="pollerProcessor">
<scripting:transformer doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[def endpointBuilder = muleContext.endpointFactory.getEndpointBuilder(
"sftp://${user}:${pwForGroovy}#${host}:${port}${inputpath}/?connector=SFTP")
endpointBuilder.addMessageProcessor(new org.mule.routing.MessageFilter(new org.mule.transport.file.filters.FilenameWildcardFilter('test.txt')))
def inboundEndpoint = endpointBuilder.buildInboundEndpoint() inboundEndpoint.request(30000L)]]>
</scripting:script>
</scripting:transformer>
<set-payload value="#[payload == null ? 'file not found' : payload]" doc:name="Set Payload"/>
</sub-flow>

Related

"Redirecting into HTML page"

I have a flow where I am trying to load a HTML page if successfully login or fails. Flow is working but while doing POST job on browser side it's not redirecting to the loginSuccessful.html or login/loginFailure.html.
<flow name="GetLoginPage">
<http:listener config-ref="HTTP_Listener_Configuration" path="/login" allowedMethods="GET" doc:name="HTTP"/>
<parse-template location="login/index.html" doc:name="Parse Template"/>
</flow>
<flow name="Dologin">
<http:listener config-ref="HTTP_Listener_Configuration" path="/login" allowedMethods="POST" doc:name="HTTP"/>
<logger message="trying to login!!!!!!!!!!!" level="INFO" doc:name="Logger"/>
<choice doc:name="Choice">
<when expression="#[payload.username == "mule" and payload.password == "mule"]">
<logger message="login successfully!!!!!!!!!!!" level="INFO" doc:name="Logger"/>
<parse-template location="login/loginSuccessful.html" doc:name="Parse Template"/>
</when>
<otherwise>
<logger message="login failed!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" level="INFO" doc:name="Logger"/>
<parse-template location="login/loginFailure.html" doc:name="Parse Template"/>
</otherwise>
</choice>
</flow>
I took the liberty of creating my own payload in JSON and added the payload values from above:
{
"name": "mule",
"password": "mule"
}
Then, added a data transformer from JSON to Java, then I mildly adjusted your conditional test to eliminate the encoded quotes and replaced them with single quotes:
payload.username == 'mule' and payload.password == 'mule'
And the choice router correctly to pick up my test files with the parse template.

Mule batch job taking too long to enrich data

I am trying to enrich the data to create an XML file.
The first query does a Group By to obtain the transaction header.
The second query gets all records (details) that match the header from the same file, to enrich the message.
The problem is that it takes about a second to run the query that enriches the data. I will need to run this process for 184,764 headers. At one second per header this job will take too long. Is there a way to accomplish the same thing without having to query the database for details? Can all the records be loaded first and obtain the details from memory instead? Here's the code:
<db:generic-config name="Generic_Database_Configuration" url="${db.url}"
driverClassName="${driver.class.name}" doc:name="Generic Database
Configuration"/>
<data-mapper:config name="List_Map__To_List_Map_"
transformationGraphPath="list_map__to_list_map_.grf"
doc:name="List_Map__To_List_Map_"/>
<data-mapper:config name="List_Map__To_XML_1"
transformationGraphPath="list_map__to_xml_1.grf"
doc:name="List_Map__To_XML_1"/>
<batch:job name="OrceTransactionImportBatch">
<batch:input>
<db:select config-ref="Generic_Database_Configuration"
doc:name="Database">
<db:parameterized-query><![CDATA[SELECT TRANDATED, STORED, REG#D
AS REG_D, TRAN#D AS TRAN_D, VIP#D AS VIP_D, VIP#D AS VIPNO, SUM(RETAIL*QTY)
AS TOTAL,
CONCAT(SUBSTRING(TRANDATED,1,4),
CONCAT('-',CONCAT(SUBSTRING(TRANDATED,5,2),
CONCAT('-',CONCAT(SUBSTRING(TRANDATED,7,2),'T00:00:00'))))) AS
BusinessDayDate
FROM ORCTEXDTLP
WHERE DGROUPID IN (SELECT HGROUPID FROM ORCTEXHDRP WHERE HPRCFLAG = 'P')
GROUP BY STORED, TRANDATED, REG#D, TRAN#D, VIP#D
FETCH FIRST 60 ROWS ONLY]]></db:parameterized-query>
</db:select>
<logger message="before mapper..." level="INFO" doc:name="before
mapper..."/>
</batch:input>
<batch:process-records>
<batch:step name="Batch_Step">
<data-mapper:transform config-ref="List_Map__To_List_Map_"
doc:name="List<Map> To List<Map>"/>
<logger message="before enricher..." level="INFO"
doc:name="before enricher..."/>
</batch:step>
<batch:step name="Batch_Step1">
<logger message="BEFORE FOR EACH..." level="INFO"
doc:name="Logger"/>
<enricher target="#[variable:LineItem]" doc:name="Message
Enricher">
<db:select config-ref="Generic_Database_Configuration"
doc:name="Database">
<db:parameterized-query><![CDATA[SELECT TRANCODED,
CONCAT(SUBSTRING(TRANDATED,1,4),
CONCAT('-',CONCAT(SUBSTRING(TRANDATED,5,2),
CONCAT('-',CONCAT(SUBSTRING(TRANDATED,7,2),'T00:00:00'))))) AS
BusinessDayDate, STORED AS RetailStoreID, TRAN#D AS TransactionNumber, REG#D
AS WorkstationID, RETAIL AS TransactionGrandAmount, VIP#D AS AlternateID,
DISCOUNT, VOUCHER#D AS VOUCHER_D, TRIM(SKU#) AS ItemID, A03K2 AS
UnitCostPrice, RETAIL AS RegularSalesUnitPrice, (RETAIL*QTY) AS
ExtendedAmount, QTY AS Quantity, ROW_NUMBER() OVER () rownumber,
(RETAIL*QTY) AS ActualRetail,
VOUCHERCD AS VoucherCode, VOUCHER#D AS VoucherNumber
FROM FBF02P
LEFT OUTER JOIN KSK2P ON SKUK2 = SKU#
WHERE TRANDATED = #[payload[0]['TRANDATED']] AND STORED = #[payload[0]
['STORED']] AND REG#D = #[payload[0]['REG_D']] AND TRAN#D = #[payload[0]
['TRAN_D']]]]></db:parameterized-query>
</db:select>
</enricher>
<expression-component doc:name="Expression"><![CDATA[#
[payload[0].LineItem=flowVars.LineItem]]]></expression-component>
<logger message="#[payload[0]['TRAN_D']]" level="INFO"
doc:name="Logger"/>
</batch:step>
<batch:step name="Batch_Step2">
<batch:commit streaming="true" doc:name="Batch Commit">
<data-mapper:transform config-ref="List_Map__To_XML_1"
doc:name="List<Map> To XML"/>
<file:outbound-endpoint path="${output.path}"
outputPattern="TranImport#[server.dateTime.format('yyyyMMdd_HHmmss')].xml"
responseTimeout="10000" doc:name="File"/>
</batch:commit>
</batch:step>
</batch:process-records>
<batch:on-complete>
<logger message="DONE..." level="INFO" doc:name="Logger"/>
</batch:on-complete>
</batch:job>
<flow name="OrceTransactionImportFlow">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="1" timeUnit="DAYS"/>
<db:update config-ref="Generic_Database_Configuration"
doc:name="Database">
<db:parameterized-query><![CDATA[UPDATE ORCTEXHDRP
SET HPRCFLAG = 'P'
WHERE HPRCFLAG = '' OR HPRCFLAG = 'P']]></db:parameterized-query>
</db:update>
</poll>
<choice doc:name="Choice">
<when expression="#[payload == 0]">
<logger message="Zero payload..." level="INFO"
doc:name="Logger"/>
</when>
<otherwise>
<batch:execute name="OrceTransactionImportBatch"
doc:name="OrceTransactionImportBatch"/>
</otherwise>
</choice>
</flow>
Inside your database connector configuration you should setup a Connection Pooling profile.

Mule Flow Reference Component throwing TransformerMessagingException while passing json

I have two flow one receive the xml payload and another json. I am routing the xml call to json flow using mule flow reference component after converting the xml to json payload. and second flow returns the json payload that i need to convert back to xml and reply to client.
My mule flow reference is throwing TransformerMsgException while receiving the json response from second flow.
Failed to transform from "json" to "java.lang.String" (org.mule.api.transformer.TransformerException). Message payload is of type: String
Here are the code for your reference -
<flow name="post:/chkdb:application/json:chkd-config">
<logger message="========json payload==>>>>==== #[message.payload]" level="INFO" doc:name="Logger"/>
<set-variable variableName="GGG_Number" value="#[json:ggg]" doc:name="Variable"/>
<!-- db call returns the payload-->
<choice doc:name="Choice">
<when expression="#[message.payload.size()>0]">
<set-payload value="{"indicator":"True"}" mimeType="application/json" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="{"indicator":"False"}" mimeType="application/json" doc:name="Set Payload"/>
</otherwise>
</choice>
<logger message="=========after producing json output=======" level="INFO" doc:name="Logger"/>
</flow>
<flow name="post:/chkdb:application/xml:chkdb-config">
<logger message="========= xml payload======== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:xml-to-json-transformer mimeType="application/json" doc:name="XML to JSON"/>
<flow-ref name="post:/chkdb:application/json:chkdb-config" doc:name="post:/chkdb:application/json:chkdbapi-config"/> <!-- Getting exception here -->
<logger message=" after subflow call ==== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:json-to-xml-transformer mimeType="application/xml" doc:name="JSON to XML"/>
<logger message="after json to xml conversion" level="INFO" doc:name="Logger"/>
</flow>
XML Request -
<ggg>DeJmp03bkqALlRFYmgu4+A==</ggg>
How i should retrieve the json response from other flow to current flow.
There is something missing here
First flow name: post:/chkdb:application/json:chkdbapi-config
Second flow name: post:/chkdb:application/xml:chkdbapi-config
Flow ref in second flow: post:/chkdb:application/json:chkdb-config
You are not referencing First flow.
So from your flow posted I can find few issues as follows :-
1. You are using where is the flow post:/chkdb:application/json:chkdb-config doesn't exits and it should be post:/chkdb:application/json:chkdbapi-config instead
2. Right now in the flow you are using <when expression="#[message.payload.size()>0]"> where as the message payload is in String format right now.
So, you can either use <when expression="#[message.payload.length()>0]">, using length() instead of size() or put a <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object"/>before choice if you use #[message.payload.size()>0]
So the full code will be something as follows :-
<flow name="post:/chkdb:application/json:chkdbapi-config">
<logger message="========json payload==>>>>==== #[message.payload]" level="INFO" doc:name="Logger"/>
<!-- <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object"/> --> <!-- incase you use #[message.payload.size()>0] in your choice -->
<!-- db call returns the payload-->
<set-variable variableName="GGG_Number" value="#[json:ggg]" doc:name="Variable"/>
<choice doc:name="Choice">
<when expression="#[message.payload.length()>0]">
<set-payload value="{"indicator":"True"}" mimeType="application/json" doc:name="Set Payload"/>
</when>
<otherwise>
<set-payload value="{"indicator":"False"}" mimeType="application/json" doc:name="Set Payload"/>
</otherwise>
</choice>
<logger message="=========after producing json output=======" level="INFO" doc:name="Logger"/>
</flow>
<flow name="post:/chkdb:application/xml:chkdbapi-config">
<logger message="========= xml payload======== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:xml-to-json-transformer mimeType="application/json" doc:name="XML to JSON"/>
<flow-ref name="post:/chkdb:application/json:chkdbapi-config" doc:name="post:/chkdb:application/json:chkdbapi-config"/> <!-- Getting exception here -->
<logger message=" after subflow call ==== #[message.payload]" level="INFO" doc:name="Logger"/>
<json:json-to-xml-transformer mimeType="application/xml" doc:name="JSON to XML"/>
<logger message="after json to xml conversion" level="INFO" doc:name="Logger"/>
</flow>

How do you remove Attachements in an email to email flow?

I was trying to remove an attachment so that my outbound email only contains the payload. I used the attachment transformer but the attchments are still being sent even if I used "*" as the filter. I have placed it on the inbound and the outbound endpoint but the attchment is still appering on the email
<remove-attachment attachmentName=""*"" doc:name="Attachment"/>
<flow name="ocr_app_testFlow">
<pop3:inbound-endpoint host="mail.awh.com.au" user="knaufack" password="ocr123" responseTimeout="10000" doc:name="POP3"/>
<logger message="#[message.inboundProperties.subject]" level="INFO" doc:name="Logger"/>
<remove-attachment attachmentName="*" doc:name="Attachment"/>
<choice doc:name="Choice">
<when expression="#[wildcard('*Succeeded*',message.inboundProperties.subject)]">
<set-variable variableName="Subject" value="#[message.inboundProperties.subject]" doc:name="Variable"/>
<set-variable variableName="Warehouse" value="#[message.inboundProperties.subject.substring(40,43)]" doc:name="Variable"/>
<set-variable variableName="Order" value="#[message.inboundProperties.subject.substring(44,51)]" doc:name="Variable"/>
</when>
<otherwise>
<set-variable variableName="Subject" value="#[message.inboundProperties.subject]" doc:name="Variable"/>
<set-variable variableName="Warehouse" value="#[message.inboundProperties.subject.substring(37,40)]" doc:name="Variable"/>
<set-variable variableName="Order" value="#[message.inboundProperties.subject.substring(41,48)]" doc:name="Variable"/>
</otherwise>
</choice>
<logger message="#[flowVars.Order] from #[flowVars.Warehouse]" level="INFO" doc:name="Logger"/>
<set-payload value="Your Order #[flowVars.Order] from #[flowVars.Warehouse] Warehouse is imported succesfully. Please Verify" doc:name="Set Payload"/>
<remove-attachment attachmentName="*" doc:name="Attachment"/>
<choice doc:name="Choice">
<when expression="#[flowVars.Warehouse == 'ROC']">
<smtp:outbound-endpoint host="mail.awh.com.au" user="tupload" password="upload123" to="tupload#awh.com.au" from="AWH_Logistics_Integration" subject="AWH OCR Process Notification" responseTimeout="10000" doc:name="ROC Warehouse"/>
</when>
<otherwise>
<smtp:outbound-endpoint host="mail.awh.com.au" user="tupload" password="upload123" to="pauldominguez#awh.com.au" from="AWH_Logistics_Integration" subject="AWH OCR Process Notification" responseTimeout="10000" doc:name="SMTP"/>
</otherwise>
</choice>
</flow>
Add the attached transformer class to your project.
package org.awh.pfinder;
import org.mule.transport.email.transformers.ObjectToMimeMessage;
public class RemoveAttachmentTransformer extends ObjectToMimeMessage {
public RemoveAttachmentTransformer() {
super();
setUseInboundAttachments(false);
}
}
Add an SMTP connector and set that transformer as the outbound one:

Mule: How to use until successfull processor for service calls

Please help me on this logic. I have to call the service and get the response back.If the service is down or something have to retry 3 times and once exhausted need to log in DLQ.I'm using until successful processor.For success scenario i'm getting only null payload in logger.But i tried keeping the HTTP outbound end point without until successfull able to get the response from the service. Please find my xml config.
<flow name="Flow" doc:name="eFlow" tracking:enable-default-events="true">
<wmq:inbound-endpoint queue="InputQ" tracking:enable-default-events="true" connector ref="WMQ_Connector" doc:name="connector">
<wmq:transaction action="NONE"/>
</wmq:inbound-endpoint>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<set-session-variable variableName="originalPayload" value="#[payload]" doc:name="Store_Payload"/>
<choice tracking:enable-default-events="true" doc:name="Choice">
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Master']">
<data-mapper:transform config-ref="Master_grf" doc:name="Master"/>
</when>
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Request']">
<data-mapper:transform config-ref="Request_grf" doc:name="Bulk"/>
</when>
<otherwise>
<scripting:component doc:name="Throw_Exception">
<scripting:script engine="Groovy"><![CDATA[throw new IllegalArgumentException ('requests invalid') ]]>
</otherwise>
</choice>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<flow-ref name="Invoke_Service" doc:name="Flow Reference"/>
</flow>
<flow name="Invoke_Service" doc:name="Invoke_Service" tracking:enable-default-events="true">
<cxf:jaxws-client enableMuleSoapHeaders="true" doc:name="SOAP" operation="Request" serviceClass="com.valid.ICase"/>
<until-successful objectStore-ref="objectStore" maxRetries="3" secondsBetweenRetries="2" deadLetterQueue-ref="VM" doc:name="UntilSuccessful_SymboticService">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" address="http://localhost:1112/symbotic"/>
</until-successful>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="**********success***Payload: #[payload]*****" level="INFO" doc:name="Logger"/>
But incase of failure scenario until success retry 3 times ( works fine). I have tried request reply processor inside until also transactional processor. It is not working. Using Mule version 3.4.kindly suggest me.
Retried the same with request -reply processor as per the suggestion
<flow name="Flow" doc:name="eFlow" tracking:enable-default-events="true">
<wmq:inbound-endpoint queue="InputQ" tracking:enable-default-events="true" connector- ref="WMQ_Connector" doc:name="connector">
<wmq:transaction action="NONE"/>
</wmq:inbound-endpoint>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<set-session-variable variableName="originalPayload" value="#[payload]" doc:name="Store_Payload"/>
<choice tracking:enable-default-events="true" doc:name="Choice">
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Master']">
<data-mapper:transform config-ref="Master_grf" doc:name="Master"/>
</when>
<when expression="#[xpath('fn:local-name(/root/*[2])') == 'Request']">
<data-mapper:transform config-ref="Request_grf" doc:name="Bulk"/>
</when>
<otherwise>
<scripting:component doc:name="Throw_Exception">
<scripting:script engine="Groovy"><![CDATA[throw new IllegalArgumentException('requests other then Master andRequest') ]]>
</otherwise>
</choice>
<mulexml:dom-to-xml-transformer></mulexml:dom-to-xml-transformer>
<request-reply timeout="10000">
<vm:outbound-endpoint path="request"/>
<vm:inbound-endpoint path="reply"/>
</request-reply>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="**********success***Payload: #[payload]*****" level="INFO" doc:name="Logger"/>
</flow>
<flow name="Invoke_Service" doc:name="Invoke_Service" tracking:enable-default-events="true">
<vm:inbound-endpoint path="request" doc:name="VM"/>
<cxf:jaxws-client enableMuleSoapHeaders="true" doc:name="SOAP" operation="Request" serviceClass="com.valid.ICase"/>
<until-successful objectStore-ref="objectStore" maxRetries="3" secondsBetweenRetries="2" deadLetterQueue-ref="VM" doc:name="UntilSuccessful_Service">
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" address="http://localhost:1112/symbotic"/>
</until-successful>
</flow>
Even then getting the null payload. Kindly suggest is this is the way your were directing me. Please correct me if im wrong.
until-successful is an asynchronous processor. It does not return response from service call.
Success or failure are defined as:
If the child message processor throws an exception, this is a failure.
If the child message processor does not return a message (e.g. is a one-way endpoint), this is a success.
If a 'failure expression' (see below) has been configured, the return message is evaluated against this expression to determine failure or not.
Otherwise:
If the child message processor returns a message that contains an exception payload, this is a failure.
If the child message processor returns a message that does not contain an exception payload, this is a success.
http://www.mulesoft.org/documentation/display/current/Routing+Message+Processors#RoutingMessageProcessors-UntilSuccessful