How to get payload mime type in Mule 4 - mule

I am trying to find out what is the payload type by printing it out using logger. I am aware that in Mule 3 you could use this #[payload.getClass().getSimpleName()] or #[message.dataType.type].
How to achieve this in Mule 4? I did my google search but could not find any solution.

You can use:
#[payload.^class]
Try logging:
#[payload.^]
Should print:
{class=java.util.ArrayList, encoding=UTF-8, mimeType=application/java, raw=[{}]}
But if your payload is not application/java mime/type but json or something instead it won't have class attribute.

Get payload media type: #[payload.^mediaType]
Reference: https://docs.mulesoft.com/dataweave/2.4/dataweave-cookbook-extract-data

Related

Mule 4.4 convert Binary payload into JSON

So I have gone through a number of questions related to this topic and tried the various options but none of them seem to work .
Environment - Mule runtime 4.4 , Anypoint Studio 7.11.1
Our limitation is we are not using Enterprise edition only community edition
So cannot use Transform component . However can use dataweave in setPayload / set Variable
I am receiving payload as Binary : see below :
Data appears as JSON but is Binary
I tried changing to JSON in 'setPayload' :
%dw 2.0
import * from dw::core::Binaries
output application/json
---
fromBase64(payload)
However I get this exception :
""Unexpected character 'ÿ' at payload#[1:30] (line:column), expected
Expecting end of input but got `ÿ, while reading `payload` as Json.
1| {"Employee":{"EName":"abcd"}}
^" evaluating expression: "%dw 2.0 import * from dw::core::Binaries output application/json
--- fromBase64(payload)"."
Note - also tried to check datatype of payload using :
typeOf(payload)
This too gave the same exception as above ...
Please help
Update 1:
Based on comments from #aled few additional details :
I am making a GET request to my api endpoint which is reading data from an ERP system which returns data in XML
Then I use a custom component that is being used to transform the XML data to JSON
The o/p of this custom component is what is generating binary data which I am unable to parse
I agree regarding Base64 that was useless
I later even tried with Transform component and all of the below attempts failed with the same exception :
Attempt#1:
%dw 2.0
output application/json
---
if (isEmpty(payload.^raw)) {
"payload": "No payload!!"
}
else {
"payload": payload
}
Attempt#2:
%dw 2.0
output application/json
---
payload
The above XML payload is a short excerpt received from ERP
I need to parse the payload and identify if there is an error present in the payload .
NOTE : if I simply log the payload it all shows up fine in the logs.
is it not possible to convert binary data to json ? do you think there is something wrong in the data received either from ERP or in the XML to JSON Transformer ?
Update#2
So based on earlier comments from #aled ( thanks ! ) started focusing on payload o/p of the ERP component ( which is XML ) BEFORE it is fed to our custom transformer ( which is generating binary data )
Attaching screen print for clarity and will also paste non proprietary code :
Now when I inspect the payload I can see it as :
<?xml version = "1.0" encoding="utf-8" ?>
<Output>
<ErrorDetails>
<Status>1</Status>
<Details>Invalid user or organisation</Details>
</ErrorDetails>
<Employee>
<EName>abcd</EName>
</Employee>
</Output>
and in debug mode I can see that payload is String and NOT Binary
Now I can access individual elements of the payload .
Example:
<set-variable value="#[output application/java --- payload[0].ErrorDetails['Status']]"
doc:name="extract status" variableName="status"/>
So this gives me the value 1 which is expected and good .
Conclusions:
1 The component that interacts with ERP is generating Non Binary / stream data
2 This data as expected is parseable - all good here
3 AFTER this data is fed to our custom component - the o/p payload is now binary and am running into issues parsing it ...
Question:
I know this being a custom component i cannot share code details here and thereby cannot expect inputs BUT regarding #aled comments about hexdump do you think I should try and use it against the output of the custom component ?
Once again a big thanks for your patience and help
Using function fromBase64() is just wrong. The value is not a Base64 string. It doesn't makes sense to try it. Using toBase64() would be useless because you would not be able to do anything with it, other than sending it somewhere else.
Your payload seems to be a JSON, and the media type is application/json in your screenshot, but it contains an UNICODE character at the end at least. You need. What are you trying to do with that payload exactly?
If the payload is truly a binary there is nothing you can do about that in the application. If you are receiving it from somewhere else check with the source. You didn't provide details of the source. Also ensure it is not your application corrupting the payload somehow.

Mule 3 HTML as property value

I have a Mule 3 dw 1.0 application with a payload that is HTML which is produced by a parse template component (the mime type this produces is application/json). I want to use this unescaped HTML as a string value in a transform message component so I have something like:
%dw 1.0
%output application/json
---
{
"body": payload
}
however, I get an exception at this stage due to < character not being valid. I have tried converting the payload to a string, converting the payload to a string prior to this transform message, converting the JSON to an object then to a string. None of which worked.
The solution was to create a new flow variable and importantly set its MIME type to text/html.

how to pass an attribute over ActiveMQ in Mule 4

We are migrating from Mule 3 to Mule 4 and in one of our functionalities we need to publish messages to a topic and downstream another mule component is consuming from the queue which is bridged to the topic.
Nothing special here .
To ensure we are able to trace the flow via logs we were sending a 'TrackingId' attribute while publishing messages to the topic ( Mule 3 )
message.setOutboundProperty("XYZ_TrackingID", flowVars['idFromUI']);
return payload;
However when I try the same in Mule 4 we get the following exception :
ERROR 2020-12-20 10:09:12,214 [[MuleRuntime].cpuIntensive.14: [mycomponent].my_Flow.CPU_INTENSIVE
#66024695] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
Message : groovy.lang.MissingMethodException: No signature of method:
org.mule.runtime.api.el.BindingContextUtils$MessageWrapper.setOutboundProperty() is applicable for
argument types: (java.lang.String, org.mule.weave.v2.el.ByteArrayBasedCursorStream) values:
[XYZ_TrackingID, "1234567"].\nError type : (set debug level logging or '-
Dmule.verbose.exceptions=true' for
everything)\n********************************************************************************
Checked internet and it seems in Mule4 setting outbound properties is removed as per here
So how do I achieve the same in Mule 4 ?
Don't even try to do that for several reasons. For one message structure is different, so output properties doesn't exist anymore and that method doesn't even exists. On the other hand, in Mule 4 components like the Groovy component can only return a value and cannot change the event. They can not decide to what that value is going to be assigned. You can set the target in the configuration (payload or a variable) and not change the attributes. Note that variables in Mule 4 are referenced by var., not by flowVars. like in Mule 3 (ie vars.idFromUI).
There is a simpler way to set message properties in the Mule 4 JMS connector. Use the properties element and pass it an object with the properties.
For example it could be something like this:
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
XYZ_TrackingID: vars.idFromUI
}]</jms:properties>
</jms:message>
</jms:publish>
It is in the documentation: https://docs.mulesoft.com/jms-connector/1.0/jms-publish#setting-user-properties. I adapted my example from there.
I am not sure if Correlation Id serves the purpose of a tracking ID for your scenario. But you can pass a CID as below. It's there in the mule documentation.
https://docs.mulesoft.com/jms-connector/1.7/jms-publish
<jms:publish config-ref="JMS_config" sendCorrelationId="ALWAYS" destination="#[attributes.headers.replyTo.destination]">
<jms:message correlationId="#[attributes.headers.correlationId]"/>
</jms:publish>
If your priority is to customise the Tracking ID you want to publish, then try passing below format. The key names may differ as per your use case.
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
AUTH_TYPE: 'jwt',
AUTH_TOKEN: attributes.queryParams.token
}]</jms:properties>
</jms:message>
</jms:publish>
In the above the expression attributes.queryParams.token is basically trying to access a token query parameters which is passed to JMS as a property AUTH_TOKEN key-name , consumed by the API through a HTTP Listener or Requestor earlier.
However, attributes.headers.correlationId is a header. Both queryParams and headers are part of attributes in Mule 4.

Unknown Payload in transform message Anypoint Studio

I have a problem with transform message. I need to recieve messages in SOAP/WSDL sistem. In my case i have this structure for process the responses.
This is my flow and in trnasform message component i have this problem:
Y put credentials in transform message but if i see the web service component, say that payload is unknown.
The problem is the sem for two transform message. I don't know how can i do to put the credentials good for doing a reception message aplication with SOAP/WSDL sistem.
Thanks for help.
Please try to log the payload as [message.payloadAs(java.lang.String)]
If you can see the actual payload in XML or JSON format whatever you are POSTing, then extract the specific elements.
If your GET then in query params retrieve them using [message.inboundProperties.'httpqueryparams']
Extract the specfic elements into flowvars and set them to Webservice consumer add [flowVars.userid] and [flowVars.pwd]
That will echo back as response.
I hope this is going to help.
Bit of a guess here because you haven't shown exactly what your WSDL is expecting:
I think you may want a transform a bit like this
%dw 1.0
%output application/xml encoding="UTF-8"
---
{
gdspHeader #(xmlns: "http://ws.gdsp.vf.gdspcustomer.com/" ) :{
gsdpCredentials: {
password: "Mule",
userId: "Monty"
}
}
}
Which transforms to
<?xml version='1.0' encoding='UTF-8'?>
<gdspHeader xmlns="http://ws.gdsp.vf.gdspcustomer.com/">
<gsdpCredentials>
<password>Mule</password>
<userId>Monty</userId>
</gsdpCredentials>
</gdspHeader>

Mule Merge HTTP response message

I am using MULE and 3 transformers, 2 that that require information from an HTTP response + a POJO. Transformer 2 and 3 only get the HTTP POST repsonse now and not the POJO.
Transformer1 gets a POJO and transforms it , sends it to a HTTP endpoint, it uses a Post request.
The response of the POST is used in transformer 2 and 3, however they
also need the POJO that to do their transformation !
How can I use the pojo that was used in Transformer 1 + the http response in transformer
2 and 3? I want a message to enter the ALL control flow with the payload = http response + the POJO.
Is it possible to add the two in a message e.g 2 payloads in 1 message ? How can I solve this issue?
Thanks in advance.
Mule Flow:
You can store the original POJO payload as a message property to access it later in the flow. See here for an introduction to the Mule message property scopes:
http://blogs.mulesoft.org/mule-school-the-mulemessage-property-scopes-and-variables/