Mule flatten arrays with one of the arrays as null - mule

I am learning mule4 and while trying out scatter-gather, i have run into an issue.
There are 3 flows in the scatter gather task, 2 of these flows return valid payload with data but the 3rd flow returns a empty payload.
thus when i am trying to flatten these 3 results , i am running into null pointer issue. i am not able to make out way to handle this. can anybody help please.
My dataweave expression is as below
%dw 2.0
output application/java
---
flatten(payload..payload)
logs
ERROR 2018-10-27 07:10:00,249 [[MuleRuntime].cpuLight.06: [apdev-flights-ws].getAllFlightsFlow.CPU_LITE #5abc6c4c] [event: ] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
********************************************************************************
Message : "Unexpected end-of-input at payload#[1:1] (line:column), expected false or true or null or {...} or [...] or number but was , while reading `payload`as Json.
1|
^" evaluating expression: "%dw 2.0
output application/java
---
flatten(payload..payload) ".
Error type : MULE:EXPRESSION
Element : getAllFlightsFlow/processors/2 # apdev-flights-ws:implementation.xml:102 (Flatten)
Element XML : <ee:transform doc:name="Flatten" doc:id="46245fd1-5ebd-4b16-b83e-31ea4dbb53e8">
<ee:message>
<ee:set-payload>%dw 2.0
output application/java
---
flatten(payload..payload)</ee:set-payload>
</ee:message>
</ee:transform>
(set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
INFO 2018-10-27 07:10:00,323 [[MuleRuntime].cpuLight.06: [apdev-flights-ws].getAllFlightsFlow.CPU_LITE #5abc6c4c] [event: ] org.mule.runtime.core.internal.context.notification.Policy: NotificationListener com.mulesoft.mule.debugger.server.DebuggerPipelineMessageNotificationListener#20d9c50f was unable to fire notification PipelineMessageNotification{action=pipeline process complete, resourceId=getAllFlightsFlow, serverId=de-PC..apdev-flights-ws, timestamp=1540604400323} due to an exception: java.lang.NullPointerException.

I believe it's the payload..payload call that's messing you up. If you want to flatten the payload, it should just be:
%dw 2.0
output application/java
---
flatten(payload)

Related

Issues Migrating Mule 3.6 expression component into DataWeave 2.0

My company is moving toward migrating our current Mule 3.6 APIs into Mule 4.2 and I'm trying to migrate our first API at present. There are numerous differences between the runtimes not least the wide use of Dataweave 2.0 in Mule 4. I'm new to a lot of the components of Mule 4 having used Mule 3 extensively, and I'm currently stuck with moving the following expression component into Dataweave. I'm struggling to get the correct syntax without Studio complaining that there are errors.
The current expression is
<expression-component doc:name="Expression"><![CDATA[
flowVars.pSector="ELECTRICITY";
if(flowVars.serialNo.length()==14){
if (flowVars.serialNo.substring(0,2)=="G4" || flowVars.serialNo.substring(0,2)=="E6" ||
flowVars.serialNo.substring(0,2)=="JE" || flowVars.serialNo.substring(0,2)=="JA" ||
flowVars.serialNo.substring(0,2)=="JS") {
flowVars.pSector="GAS";
}
}]]></expression-component>
this is essentially determining the fuel type of a meter based on component parts of its serial number and it's length. Any help on converting this expression into a Dataweave would be appreciated
Note that in Mule 4 there can not be side effects, meaning that you can assign the result of one script to the payload or to one variable. Also DataWeave is functional rather than an imperative language.
In Mule 4 variables are referenced as vars.name instead of flowVars.name.
A naive translation could be like this:
<ee:transform doc:name="Transform Message">
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
fun checkSerial(serial)=if (sizeOf(serial) == 14 )
if (serial[0 to 1] == "G4" or serial[0 to 1]=="E6" or serial[0 to 1]=="JE"
or serial[0 to 1]=="JA" or serial[0 to 1]=="JS")
"GAS"
else
"ELECTRICITY"
else "ELECTRICITY"
---
checkSerial(vars.serialNo)]]></ee:set-payload>
</ee:message>
</ee:transform>

How to get more information about dataweave exception in muleosft

I am getting below dataweave exception while executing a mule flow :
"
INFO 2016-11-06 09:02:42,097 [[abc].HTTP_Listener_Configuration.worker.01] com.mulesoft.weave.mule.utils.MuleWeaveFactory$: MimeType was not resolved '*/*' delegating to Java.
ERROR 2016-11-06 09:02:42,290 [[abc].HTTP_Listener_Configuration.worker.01] org.mule.exception.CatchMessagingExceptionStrategy:
Message : Exception while executing:
"Response": {
^
Unexpected character '\u000a' at index 25 (line 2, position 24), expected '"'
Payload : test
Payload Type : java.lang.String
Element : /Process11/processors/9/1/9 # abc:def.xml:331 (TM_F1)
Element XML : <dw:transform-message doc:name="TM_F1">
<dw:set-payload>%dw 1.0%output application/json---{Data: [{// in_id : flowVars.instanceId,pd: '{AmIds:[{AmId:' ++ flowVars.AmId ++ '}]}'}]}</dw:set-payload>
</dw:transform-message>
Root Exception stack trace:
com.mulesoft.weave.reader.json.JsonReaderException: Unexpected character '\u000a' at index 25 (line 2, position 24), expected '"'
at com.mulesoft.weave.reader.json.JsonTokenizer.fail(JsonTokenizer.scala:193)
at com.mulesoft.weave.reader.json.JsonTokenizer.require(JsonTokenizer.scala:190)
at com.mulesoft.weave.reader.json.JsonTokenizer.readString(JsonTokenizer.scala:80)
"
Is there any possibility to enable more debug options to get more information about this particular exception so that it will be easy to find out the root cause.
The problem here is, even though i am not using the payload in transform message i am getting error because of the payload returned by the previous http call in muleflow.
Mule version is : studio 6.1 and runtime 3.8.
Please help me to solve this issue.
Thanks
sdg
This is not dataweave question. Exception what you have is from JsonReaderException:
com.mulesoft.weave.reader.json.JsonReaderException: Unexpected character '\u000a' at index 25 (line 2, position 24), expected '"'
It means that JSON what you provide has new line (\u000a) ate line 2 position 24. I imagine it is something like this:
"Response": {
"Message" : "67890123
456 the end"
}
Use special characters to represent new line in JSON.
"Response": {
"Message" : "67890123\n456 the end"
}
Enable info logs in log4j and enable debug logs at cloudhub if its an on cloud deployment.
Please Try validating the json as well
Debug is the best option to figure out these kind of errors. Also you may use the logger feature of dataweave to log specific values on console and see whats wrong with the value.

Mule ExpressionRuntimeException Message payload is of type: LinkedList

error message:
Message : Execution of the expression "payload.get(0).get('ACCESS_TOKEN')" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: LinkedList
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. Index: 0, Size: 0 (java.lang.IndexOutOfBoundsException)
java.util.LinkedList:553 (null)
2. null (java.lang.reflect.InvocationTargetException)
sun.reflect.GeneratedMethodAccessor323:-1 (null)
3. cannot invoke method: get (java.lang.RuntimeException)
org.mule.mvel2.optimizers.impl.refl.nodes.MethodAccessor:63 (null)
4. Execution of the expression "payload.get(0).get('ACCESS_TOKEN')" failed. (org.mule.api.expression.ExpressionRuntimeException)
org.mule.el.mvel.MVELExpressionLanguage:202 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
5. Execution of the expression "payload.get(0).get('ACCESS_TOKEN')" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: LinkedList (org.mule.api.transformer.TransformerMessagingException)
code:
<db:select config-ref="QB_Oracle_Configuration" doc:name="Access">
<db:parameterized-query><![CDATA[select access_token, access_token_secret from sias_access where EMPLID=#[message.inboundProperties['p_emplId']] AND TRINET_COMPANY=#[message.inboundProperties['p_company']]]]></db:parameterized-query>
</db:select>
<set-session-variable variableName="accessToken" value="#[payload.get(0).get('ACCESS_TOKEN')]" doc:name="Access token"/>
Problem is sometime value comes more than one from select query, how do I filter. I can do by filtering query by WHERE ROWNUM = 1, but how can I handle in Mule instead of this in query?
Can you try with:
#[message.payload[0]['ACCESS_TOKEN']]
If this still throws an exception, please share the full ERROR not just the first line so I can refine my answer.

MuleSoft - use decryption with null paylod

I'm trying to use MuleSoft's decryption on HTTP requests. I'm doing this also on GET requests.
I get the following error:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ERROR 2015-05-17 13:00:35,630
[[broker1-secure].HTTP_Listener_Configuration.worker.01]
org.mule.exception.DefaultMessagingExceptionStrategy:
******************************************************************************** Message : Failed to invoke decrypt. Message payload is
of type: NullPayload Code : MULE_ERROR-29999
-------------------------------------------------------------------------------- Exception stack is:
1. Could not decrypt the input. The input has to be a byte array,Input Stream or String (java.lang.RuntimeException)
org.mule.modules.security.encryption.encrypters.JCEEncrypterModule:59
(null)
2. Failed to invoke decrypt. Message payload is of type: NullPayload (org.mule.api.MessagingException)
org.mule.devkit.processor.DevkitBasedMessageProcessor:128
(http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
-------------------------------------------------------------------------------- Root Exception stack trace: java.lang.RuntimeException: Could not
decrypt the input. The input has to be a byte array,Input Stream or
String at
org.mule.modules.security.encryption.encrypters.JCEEncrypterModule.decrypt(JCEEncrypterModule.java:59)
at
org.mule.modules.security.encryption.EncryptionModule.decrypt(EncryptionModule.java:213)
at
org.mule.modules.security.encryption.processors.DecryptMessageProcessor$1.process(DecryptMessageProcessor.java:165)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
Shouldn't it be possible? Try to decrypt payload, and if nothing to decrypt then continue?
It would be better to only decrypt if the payload is not null: it's better to avoid raising exceptions if you can.
For this, you can use a choice router to decrypt only if the payload is not null.

Mule: How to make sure payload is in writable state before doing file outbound

In my <catch-exception-strategy>, I write error payload to file. But sometimes when flow involves web-service calls and host is unavailable or unknown (for e.g. java.net.UnknownHostException is thrown), payload is not anymore an instance of InputStream or String. If I try to log error then to file, following exception is thrown:
exception.AbstractExceptionListener (AbstractExceptionListener.java:299) -
********************************************************************************
Message : Could not find a transformer to transform "SimpleDataType{type=org.apache.commons.httpclient.methods.PostMethod, mimeType='*/*'}" to "SimpleDataType{type=java.io.InputStream, mimeType='*/*'}".
Code : MULE_ERROR-65237
--------------------------------------------------------------------------------
Exception stack is:
1. Could not find a transformer to transform "SimpleDataType{type=org.apache.commons.httpclient.methods.PostMethod, mimeType='*/*'}" to "SimpleDataType{type=java.io.InputStream, mimeType='*/*'}". (org.mule.api.transformer.TransformerException)
org.mule.registry.MuleRegistryHelper:252 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.mule.api.transformer.TransformerException: Could not find a transformer to transform "SimpleDataType{type=org.apache.commons.httpclient.methods.PostMethod, mimeType='*/*'}" to "SimpleDataType{type=java.io.InputStream, mimeType='*/*'}".
at org.mule.registry.MuleRegistryHelper.lookupTransformer(MuleRegistryHelper.java:252)
at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:355)
at org.mule.DefaultMuleMessage.getPayload(DefaultMuleMessage.java:313)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
I am thinking of doing a choice block before writing to file to make sure payload is writable. Shall I do something like #[payload instanceof java.io.InputStream]? But then how about cases where payload is DOM or something else? Please advise.
I would use a transformer inside the catch exception strategy and encapsulate there the logic that would consider the input and produce a writable payload.
If you want to check whether there is a transformer available for a specific payload type and output type, I guess you could look up the available transformers from the registry. In Groovy:
transformers = message.getMuleContext().getRegistry().lookupTransformers(
new org.mule.transformer.types.SimpleDataType(payload.getClass()),
new org.mule.transformer.types.SimpleDataType(java.io.InputStream))
if (transformers.size() == 0) {
//set some variable or whatever
}