How to convert org.glassfish.grizzly.utils.BufferInputStream to JSON in Mule? - mule

On my first steps with Mule I'm writing a basic Http Proxy.
Currently I forward the request to the api server and what I'd like to do is reading the payload that I receive from it before responding to the client.
When I try to log it with #[payload] it prints
org.glassfish.grizzly.utils.BufferInputStream#2306df30
How can I print it properly in JSON format?
The full code:
<flow name="proxy">
<http:listener config-ref="http-lc-0.0.0.0-8081" path="![p['proxy.path']]" parseRequest="false"/>
<http:request config-ref="http-request-config" method="#[message.inboundProperties['http.method']]"
path="#[message.inboundProperties['http.request.path'].substring(message.inboundProperties['http.listener.path'].length()-2)]" parseResponse="false">
<http:request-builder>
<http:query-params expression="#[message.inboundProperties.'http.query.params']"/>
</http:request-builder>
<http:success-status-code-validator values="0..599" />
</http:request>
<logger doc:name="Logger" level="INFO" message="Payload #[payload]"/>

The payload after HTTP request is generally in stream format, ref:- https://docs.mulesoft.com/mule-user-guide/v/3.7/http-request-connector
There are two ways you can get the payload after http:request
1) <object-to-string-transformer doc:name="Object to String"/> after http:request
or
2) using a logger and use MEL expression <logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>

Try #[message.payloadAs(java.lang.String)] which will log the expected output.
Hope this helps.

The http component will send as InputStream,So use byte array to string transformer after http component.If you just want to print you can use #[message.payloadAs(java.lang.String)] but you wanna do any operation just drag and drop a byte array to string transformer

Simplest way is to just use <object-to-string-transformer doc:name="Object to String"/> after http request component and then place a logger with #[payload].

One way to make sure that you get proper JSON response is to set payload as application/json mimetype.
<set-payload value="#[payload]" mimeType="application/json" doc:name="Set Payload"/>
Add this line after the HTTP Request. Just setting the payload value as #[payload] will convert it to json While converting it to string will just print it as string and not make it Json type.

Related

How to concatenate in mule logger?

I need to concatenate text with json payload in logger component. I have tried below ways but no luck
<logger level="INFO" doc:name="Logger" doc:id="38de876a-a64f-4d83-86a1-ef4cbbda167c" message="#['payload is:' + payload]"/>
Even i don't see any transformers like 'object to string converter' in mule 3.
Please suggest syntax for mule 4
Try separating the text from your dataweave
i.e.
<logger level="INFO" doc:name="Logger" mesage="Payload is: #[payload]" doc:id="38de876a-a64f-4d83-86a1-ef4cbbda167c" />
All the various transformers were removed in Mule 4 due to the payload always being "accessible". That is, regardless of the payload type (XML, JSON, Java, CSV...) you can access fields through payload.{fieldname}. In Mule 3.x the payload had to be coerced to a Java object to allow that. You can explicitly set the output type of any dataweave expression, so you can also try:
mesage="Payload is: #[output application/java --- payload]"
It is working with below syntax
<logger level="INFO" doc:name="Logger" doc:id="38de876a-a64f-4d83-86a1-ef4cbbda167c" message="#['payload is:' ++ payload]"/>
I had the same issue and the below worked for me...
<logger level="INFO" doc:name="Logger" doc:id="35d4566e-02ba-495a-bd40-c30aa5a90413" message="#['Get Accounts Response Paylaod : #[payload]']"/>

Sending email attachment in Mule - Why am I getting payload attachment

I am sending an email with a csv attachment in Mule using the SMTP connector.
The email generated from Mule has two attachments on it.
The first is a file named Payload.
The second is the file I explicitly added myFile<date>.csv
How can I get rid of the Payload attachment? From my understanding what is in Payload file should be appearing as the content of the email. But that is not quite what is happening and instead it is appearing as an attachment.
Here is what my sub-flow that sends the email looks like. The payload coming in is a csv.
<sub-flow name="paymentReconSendMailSubFlow">
<set-attachment attachmentName="myFile-#[server.dateTime.format("yyyyMMddHHmmss") + '.csv']" value="#[payload]" contentType="application/csv" doc:name="Attachment"/>
<set-payload doc:name="Set Payload" value="#[null]"/>
<smtps:outbound-endpoint host="${smtp.host}" port="${smtp.port}" user="${smtp.username}" password="${smtp.password}" connector-ref="SMTP" to="${smtp.toAddress}" from="${smtp.fromAddress}" subject="BLAH" replyTo="${smtp.replyToAddress}" responseTimeout="10000" mimeType="text/html" doc:name="SMTP"/>
</sub-flow>
And here is what I get in my inbox.
It looks like Mule still has the content type of the message payload set to application/csv, so thinks your null payload is a CSV. Try adding mimeType="text/plain" to the set-payload element
Could you try to serialize the csv file to a byte array before attaching?
for example:
<file:inbound-endpoint path="${output.folder}" doc:name="File"/>
<file:file-to-byte-array-transformer doc:name="File to String"/>
<set-attachment value="#[message.payload]" contentType="application/csv"
attachmentName="#['myfile.csv']"
doc:name="Attachment" />
Let us know if is working and the issue is the serialisation of the file before sending

Mule print BufferInputStream using payloadAs

The log message below is aimed at printing out a json error response from my api.
<logger message="#[exception.getCauseException()?.getMuleMessage()?.getPayload()]" level="INFO" doc:name="Logger"/>
The result of this log message is
org.glassfish.grizzly.utils.BufferInputStream#486bf09a
I have a requirement to pass the json response. How can I turn the above log line into something like this where it will pass the stream rather than just printing BufferInputStream.toString()...
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
I tried the following below that does not work.
<logger message="#[exception.getCauseException()?.getMuleMessage().payloadAs(java.lang.String)]" level="INFO" doc:name="Logger"/>
By the way logging a stream is not the real purpose as to why I want to parse the stream. I know that is an expensive operation. I really need to pass the stream to get some meaningful information from the response.
thanks
Yes, you are correct, you are going to have to convert the output into a string to access it. Then you will have to manipulate the output using string methods to get the desired information.

Return individual values from linkedHashMap in Mule

I have an output from a webservice in Mule that returns a linkedHashMap and I need to get the individual values to be dynamically inserted into a template. The template is used to send email through the SMTP connector. I can get all values using MEL #[payload], but I can't get them one by one. I've tried #[payload.get(0)], #[payload[0]] but they all return null.
The Mule XML looks like this:
<flow name="MW_Flow">
<file:inbound-endpoint path="C:\....\1" connector- ref="File" responseTimeout="10000" doc:name="File" pollingFrequency="60000"/>
<ws:consumer config-ref="File_Read_WS" operation="all3" doc:name="FileRead DBWriter WS"/>
<dw:transform-message metadata:id="6ee92ba8-9f67-40d6-bfa3-3e237da20822" doc:name="Transform Message">
<foreach doc:name="For Each">
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<parse-template location="C:\.....\Templates\Mail.txt" metadata:id="b7d894eb-465b-47f7-a542-b49fc4fb53d9" doc:name="Parse Template"/>
<logger message="2: #[message.exception] #[message.dataType] #[payload]" level="INFO" doc:name="Logger"/>
</foreach>
</flow>
The template (plain text file) looks a bit like this:
Hello [name].
This is email from [name2]. The following event [event].....
All I get are null values except when using #[payload] which returns the whole row (4 values).
Any help greatly appreciated!
/Johan
If your payload is a Map then payload.get(0) or payload[0] will behave as if you are trying to get a value from map with 0 as key, which I guess doesn't exist in your map.
Try accessing it with name - #[payload.name] or #[payload.name2] or #[payload[name]]

To assign multiple values to a set payload transformer in mule

In order to set multiple values to a set payload transformer in mule we use
<set-payload value="#[{1000,1,1,1}]" doc:name="Set Payload"/>
can we assign multiple flow variables to a set payload transformer
<set-payload value="#[{flowVars['principal'],flowVars['years'],flowVars['rate'],flowVars['appid']}]" doc:name="Set Payload"/>
Or is there any other right way to do it
Thank you in advance
Yes, this will work just fine. Whether you can do something that looks prettier, would be up to your full flow configuration.
You can also use as following :-
<set-payload value="#[flowVars['principal']] #[flowVars['years']] ..." doc:name="Set Payload"/>