SMTP subject expression evaluation fails - mule

I have a flow where I want to evealuate an expression on the smtp subject attribute but always get mvel parse expression though the logger give me the right values.
<json:object-to-json-transformer doc:name="Object to JSON"/>
<logger message="MYRequestPayloadID #[json:RequestPayloadID] #[json:ResponseStatusCd]" level="DEBUG" doc:name="Logger"/>
<smtp:outbound-endpoint host="${mail.host}" to="${mail.to}" from="${mail.from}" subject="Error Response for PayloadID #[json:RequestPayloadID], Status #[json:ResponseStatusCd]" responseTimeout="10000" doc:name="SMTP />
I am not sure why in the subject #[json:RequestPayloadID] and #[json:ResponseStatusCd] evaluation fail though I get the data back in the logger . Thanks.

Expressions are not supported everywhere in Mule (alas): this is one place where it isn't.
You have to use message properties to set the subject dynamically:
<set-property propertyName="subject"
value="Error Response for PayloadID #[json:RequestPayloadID], Status #[json:ResponseStatusCd]" />
FTR json: is the old expression style, nowadays you should be using MEL instead: http://www.mulesoft.org/documentation/display/current/Mule+Expression+Language+Tips#MuleExpressionLanguageTips-JSONProcessing

Related

mule org.json.JSONObject returning property value as null though the json property does have value for it

I am using the below code to convert the input payload string to json in mule. The below code sometimes working and sometimes not. its not working on standalone and working on studio. Not able to nail down the exact cause for it. but based on the loggers that i see that the property value is coming null after the expression statement. i am suspecting this could be with the jar that's getting used here. i am still digging further on it.
<logger message="input: #[payload]" level="INFO" doc:name="Logger"/>
<set-payload value="#[payload.'data']" mimeType="application/json" doc:name="Set Payload" encoding="ISO-8859-2"/>
<logger message="createConnection: #[payload]" level="INFO" doc:name="Logger"/>
<expression-component doc:name="Expression"><![CDATA[String input = payload;
payload = new org.json.JSONObject(input);
]]></expression-component>
<logger message="before json to object: #[payload.con_id] #[payload.'con_id']" level="INFO" doc:name="Logger"/>
<json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object"/>
Input JSON:
data: {"name":"QA_tst2","description":"tst","con_id":10,"con_connection_id":null,
"verticalParam":[{"param_value":"abc","param_name":"Host"},{"param_value":"21","param_name":"Port"}],"CON_CATEGORY_NAME":"File"}
I don't think that notation will work for JSONObject, try using
payload.get('con_id')
as per the javadoc: https://stleary.github.io/JSON-java/org/json/JSONObject.html.
The reason this won't work with the notation you have tried, is that Mule supports that notation for Maps, and org.json.JSONObject does not implement java.util.Map. You could try using javax.json.JSONObject instead, which will support that notation.
I have figured out the current issue. if there is any logger added to fetch the properties from the payload right after the expression component then its screwing up further. if you just remove the logger that was added after the expression component then after json to object conversion, i am able to fetch the values. that solves the current issue. but i would like to understand the difference between fetching the properties #[payload.con_id] vs #[payload.'con_id']. i can start a separate conversation for the same.

How to perform string operation on JSON MEL in mule esb

I want to perform some string operation on MEL I have following expression in MEL
<logger message="#[json:xy/PID/xy.3/AC]" level="INFO" doc:name="Logger"/>
OUTPUT IS
19901026000000
I want to extract 1st 4 digit then 6,7 digit .
How can I do this ??
Thanks
What about trying it in two steps?
<set-variable variableName="result" value="#[json:ADT_A01/PID/PID.3/CX.1]" />
<set-variable variableName="result" value="#[result.substring(0,4)]#[result.substring(5,7)]" />
As noted in the comments in #Ryan Hoegg answer, the JSON expression evaluator has been deprecated since Mule 3.3 and hence the best way to do this would be to use a json to object transformer
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="java.util.HashMap"/>
and then use conventional MEL to traverse the Map
JsonPath expression are depreciated for now and you will even not get enough document on it for doing ..
So, currently you need to use either :- <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object" />
or <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object" />
or even <json:json-to-object-transformer returnClass="java.util.List" doc:name="JSON to Object" /> to extract data from JSON depending on the JSON data

How to Extract the Flow Name and MessageProcessor Name using MEL - MULE ESB

I'm not sure, how can we extract the flow-name and message-processor Name through MEL. For example I have multiple message processor. For logging, i need to extract the flow Name and Message-processor, so that I can find out transaction has crossed this particular flow and its message processor. Is there any simple way to find out. Please guide me. Please find the screenshot below. Here i need to Extract - set payload and its flowName (flow1)
Thanks in advance.
For mule 3.8+ version onwards #[flow.name] don't work.
Use #[mule:context.serviceName] expression in logger or component to extract the name of the flow
I know this post is old but I have been trying to find a way to do this in MEL for error handling emails.
For the flow name you can use #[exception.event.flowConstruct.name]
for the failing message processor you can use #[exception.failingMessageProcessor].
Both of these work in MEL without the need to use an flowVar.
Please note however, that the failing processor does not always come back with a value but comes back with null, I'm not sure why.
You can extract the flow-name with MEL : #[flow.name]
<flow name="name" doc:name="name">
<http:inbound-endpoint address="http://localhost:8090/resources" doc:name="HTTP" />
<logger message="name of flow: #[flow.name]" level="INFO" doc:name="Logger"/>
<set-payload value="name" doc:name="Set Payload"/>
</flow>
or
flowConstruct.getName() in a Message Processor
Two ways to acthive this (from current flow name)
First one is -
<logger message="Current flowName: #[flow.name]" level="INFO" doc:name="Logger"/>
and the second one is -
<logger message="Current flowName: #[context:serviceName]" level="INFO" doc:name="Logger"/>

How to parse inbound e-mail when using Mule's IMAP transport?

I am just starting to learn mule so please forgive me if this is a very basic question.
I have successfully configured mule to monitor my mail box so whenever a mail comes in I write the mail to text file (just for testing).
Now I need to parse this mail and get the message / From / To from the mail.
<flow name="testFlow" doc:name="testFlow">
<imap:inbound-endpoint host="ip"
port="143" user="username" password="pwd" doc:name="IMAP"
responseTimeout="10000" transformer-refs="Message_Properties">
</imap:inbound-endpoint>
<file:outbound-endpoint path="C:\"
outputPattern="#[function:datestamp].dat" doc:name="File">
</file:outbound-endpoint>
</flow>
I thought I would be able to get the header information using the below expression (using expression transformer)
#[inboundProperties['email-header-name']]
but this doesn't seem to work. I also tried the below expressions but didn't work,
#[map-payload:HOST]
#[map-payload:MESSAGE]
#[map-payload:TIMESTAMP]
Can someone help? Also does anyone know if there is a document with the list of available expressions?
EDIT:
I included the logger to view the properties and it displayed all the properties but I couldnt find the body.. Also, I tried getting the fromAddress using
#[map-payload:fromAddress] and #[inboundProperties['fromAddress']]
but didn't work, can someone let me know where I am wrong?
The properties are something like below,
inbound.fromAddress=Service <service#xx.com>
inbound.subject=Test Final inbound.toAddresses=Service
Edit 2:
This is what I have tried but doesnt work :(
I am trying to retrieve the email subject and write to file or just show it using logger based on email subject but I am getting the below error.
ERROR 2013-02-07 19:22:45,275 [[test].connector.file.mule.default.dispatcher.01] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Could not find a transformer to transform "SimpleDataType{type=javax.mail.internet.MimeMessage, mimeType='*/*'}" to "SimpleDataType{type=java.io.InputStream, mimeType='*/*'}".
Code : MULE_ERROR-236
Can you let me know where I am making mistake?
<flow name="testFlow1" doc:name="testFlow1">
<imap:inbound-endpoint host="ip"
port="143" user="uname" password="pwd" doc:name="IMAP"
responseTimeout="10000" disableTransportTransformer="true">
</imap:inbound-endpoint>
<logger message="#[message.inboundProperties['inbound.fromAddress']]" level="INFO" doc:name="Logger"/>
<choice doc:name="Choice">
<when expression="message.inboundProperties['inbound.subject']=='plain test'">
<processor-chain>
<logger message="#[message.inboundProperties['inbound.fromAddress']]" level="INFO" doc:name="Logger"/>
</processor-chain>
</when>
<otherwise>
<processor-chain>
<file:outbound-endpoint path="C:\mule" outputPattern="#[function:datestamp].dat" responseTimeout="10000" disableTransportTransformer="true" doc:name="File">
</file:outbound-endpoint>
</processor-chain>
</otherwise>
</choice>
</flow>
Unfortunately the IMAP connector documentation doesn't list the message properties created when a new message is received. You can find all the created properties by adding:
<logger level="WARN" />
after the imap:inbound-endpoint. This will log all the message meta information, including properties, at WARN level.
You can also find the property names in the MailProperties JavaDoc. For example inbound.fromAddress is the inbound property that contains the sender's email address.
The message body is the text email content, unless it's a multi-part email. In that case, if the first part is text/plain, it will be set as the message payload, otherwise all parts will be available as inbound message attachments.

How to log or handle original payload message in Mule

<flow>
<jms:inbound-endpoint queue="InputQueue"/>
<component class="MyComponent"/>
<choice>
<when expression="/Response/Status/Success" evaluator="xpath">
<jms:outbound-endpoint queue="LogInputQueue"/>
<jms:outbound-endpoint queue="SuccessQueue"/>
</when>
<when expression="/Response/Status/Error" evaluator="xpath">
<jms:outbound-endpoint queue="LogInputQueue"/>
<jms:outbound-endpoint queue="ErrorQueue"/>
</when>
<otherwise>
<jms:outbound-endpoint queue="LogInputQueue"/>
<jms:outbound-endpoint queue="ExceptionQueue"/>
</otherwise>
</choice>
</flow>
In this flow, MyComponent returns either success message as a response or error response or exception?
I need to log the original message from InputQueue in LogInputQueue in all the cases. How do I achieve this in my flow?
Did you mean to create a log file? In that case, you have to implement log4j using slf4j and use the line
<logger level="log_level" category="your_category" message="#[message:payload]"/>
where log_level is your desired logging level- "error", "debug", "info" etc...
your_category is your category of log defined in the log4j.properties file (it is optional actually)
and message="#[expression:value]" is your message to be logged given as an expression:scope:key combination. Scope is optional here.
Using log4j or slf4j you can log the payload.
[payload],we have logger component using this log payload in console.
Since, you need to send original message from InputQueue to LogInputQueue in all the cases, as you mentioned, what you need to do is :-
1. Remove <jms:outbound-endpoint queue="LogInputQueue"/> from all the cases in choice block
2. Store the original payload from InputQueue in a variable by placing it just after the JMS inbound endpoint
3. At the end of the flow, after the choice router, set the payload in set payload component from variable you stored the original payload
4. Now put <jms:outbound-endpoint queue="LogInputQueue"/> after your set payload component.
In this way you will able to send the original payload to the LogInputQueue as per your requirement.