Setting Map as payload in Mule Flow using MEL - mule

I am trying to generate and set a map (with 2 key value pairs) on the fly as the payload for the following HTTP call. However, the MEL expression for creating the Map is not working.
<sub-flow name="call-myservice" doc:name="call-myservice">
<set-payload value="#[username :${my.username}, password : ${my.password}]" doc:name="Set Payload"/>
<https:outbound-endpoint exchange-pattern="request-response" host="${myservice.Host}" method="POST" mimeType="application/json" doc:name="My Service call" path="mypath" port="443"/>
</sub-flow>
I followed the instructions at http://www.mulesoft.org/documentation/display/current/Mule+Expression+Language+MEL
which suggests --
MEL provides a streamlined way to access map data.
Rather than constructing a map with a new statement, and then using its put method to populate it, you can simply write the following:
[key1 : value1, key2 : value2, . . .]
However, it is giving me the following exception --
ERROR 2014-02-28 15:27:51,424 [[services-proxy].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Execution of the expression "username :abc, password : pwd" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: String
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. [Error: unresolvable property or identifier: username]
[Near : {... username :abc, pa ....}]
^
[Line: 1, Column: 1] (org.mvel2.PropertyAccessException)
org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer:687 (null)

You are missing square brackets to delimit the map (the only ones you have delimit the Mule expression). Change it to:
<set-payload value="#[['username' :${my.username}, 'password' : ${my.password}]]" doc:name="Set Payload"/>

Related

How to retrieve elements in foreach loop in Mule4?

I have defined a variable to keep application/json collection.
My original payload contain following json block;
"amendments": {
"amendmentId": ["8a9a84b76b5a5a59016b687bae35012e",
"8a9a84b76b5a5a59016b6888e90e0144"]
}
<set-variable value="#[payload..amendmentId[1]]" doc:name="AmendmentIds" doc:id="03b6c46a-fc7b-43d4-b23a-502146ef0b13" variableName="amendmentids"/>
<logger level="INFO" doc:name="Logger" doc:id="6a1ad892-65f9-4dd2-9891-bdf3ad64c908" message="#[vars.amendmentids]" />
It prints as;
[
"8a9a84b76b5a5a59016b687bae35012e",
"8a9a84b76b5a5a59016b6888e90e0144"
]
Then I use ForEach loop to define few process logic for each Id,
Within foreach loop how I can get, each above id?
I used,vars.amendmentids[vars.counter]], but getting following error[1]
<foreach doc:name="For Each" doc:id="7b741315-aa28-4704-82f0-629c21d93853" collection="#[vars.amendmentids]">
<logger level="INFO" doc:name="Logger" doc:id="049c3137-2f92-4077-8e3f-b26516cc5528" message="#[vars.amendmentids[vars.counter]]"/>
</foreach>
[1]
Message : "Internal execution exception while executing the script, this is most probably a bug, file an issue with the script and the input data.
Caused by:
java.lang.RuntimeException: Unable to infer a output media type as more than one is being used: application/json,application/java please specify using: output <your mime-type> --- <expr>
at org.mule.weave.v2.el.MuleDataWeaveHelper$.inferImplicitOutput(MuleDataWeaveHelper.scala:69)
.............
" evaluating expression: "vars.amendmentids[vars.counter]".
Error type : MULE:EXPRESSION
I fixed it by defining output mime type like;
<logger level="INFO" doc:name="Logger" doc:id="049c3137-2f92-4077-8e3f-b26516cc5528" message="#[output application/java --- vars.amendmentids[vars.counter - 1]]"/>

Mule batch commit Message payload is of type: RegularImmutableList

I have Mule batch commit as:
<batch:step name="Batch_Step1">
<enricher source="#[message.payload]" target="#[recordVars.accountJson]" doc:name="Message Enricher">
<json:object-to-json-transformer doc:name="Object to JSON"/>
</enricher>
<batch:set-record-variable variableName="client_id" value="#[message.payload.client_id]" doc:name="client_id"/>
<batch:commit size="10" doc:name="Batch Commit">
<sfdc:query config-ref="SFDC_Config" query="dsql:SELECT Id FROM Account WHERE Client_ID__c = '#[message.payload.client_id]'" doc:name="Account-Query"/>
<set-payload value="#[message.payload.hasNext() ? message.payload.next(): 'none']" doc:name="sfdc-data"/>
</batch:commit>
</batch:step>
If i don't put batch-commit, application works fine, but If i use batch-commit, I am getting below error message:
INFO 2015-07-29 14:19:44,636 [batch-job-clientaccount-Batch-work-manager.01] com.mulesoft.module.batch.DefaultBatchStep: Found exception processing record on step 'Batch_Step1' for job instance '86987df0-3637-11e5-81ea-0026b9eef95d' of job 'clientaccount-Batch'.
This is the first record to show this exception on this step for this job instance. Subsequent records with the same failureswill not be logged for performance and log readability reasons:
********************************************************************************
Message : Failed to invoke query. Message payload is of type: RegularImmutableList
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. com.google.common.collect.RegularImmutableList cannot be cast to java.util.Map (java.lang.ClassCastException)
org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessor:42 (null)
2. cannot invoke getter: getPayload [declr.class: org.mule.el.context.MessageContext; act.class: org.mule.el.context.MessageContext] (see trace) (java.lang.RuntimeException)
org.mule.mvel2.optimizers.impl.refl.nodes.GetterAccessor:74 (null)
3. Execution of the expression "message.payload.client_id" 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)
4. Failed to invoke query. Message payload is of type: RegularImmutableList (org.mule.api.MessagingException)
org.mule.devkit.processor.DevkitBasedMessageProcessor:133 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.ClassCastException: com.google.common.collect.RegularImmutableList cannot be cast to java.util.Map
at org.mule.mvel2.optimizers.impl.refl.nodes.MapAccessor.getValue(MapAccessor.java:42)
at org.mule.mvel2.optimizers.impl.refl.nodes.GetterAccessor.getValue(GetterAccessor.java:40)
at org.mule.mvel2.optimizers.impl.refl.nodes.VariableAccessor.getValue(VariableAccessor.java:37)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
Question 2)
Not able to use recordVars inside batch commit.Getting error as:
Exception stack is:
1. No record could be found in payload or in flow variable BATCH_RECORD (java.lang.IllegalStateException)
com.mulesoft.module.batch.record.BatchUtils:56 (null)
2. [Error: No record could be found in payload or in flow variable BATCH_RECORD]
[Near : {... recordVars.client_id ....}]
^
[Line: 1, Column: 1] (org.mule.mvel2.CompileException)

mule database iterating data and mapping

I am trying to fetch data from db, do mapping and upload to cloud for each record from db one by one. I have done below approach:
select data from db, map each record from the db, then upload.
Mule flow:
<flow name="psi2sfdcFlow2" doc:name="psi2sfdcFlow2">
<http:inbound-endpoint exchange-pattern="request-response" host="${hostname}" port="${port}" path="psi2sfdc" doc:name="HTTP"/>
<flow-ref name="psi-update-Reading" doc:name="Flow Reference"/>
<db:select config-ref="PostgreSQL" doc:name="PSI-Select">
<db:parameterized-query><![CDATA[SELECT * FROM clients_int WHERE int_status = 'Reading']]></db:parameterized-query>
</db:select>
<object-to-string-transformer returnClass="java.lang.Object" doc:name="Object to String"/>
<foreach doc:name="For Each">
<invoke name="db2sfdcmapping" object-ref="createAccount" method="getPayloadData" methodArguments="#[message.payload]" doc:name="Invoke"/>
<logger message="===Uplaod each row from db to cloud==== " level="INFO" doc:name="Logger"/>
</foreach>
</flow>
Error:
ERROR 2015-06-17 14:24:56,735 [[psi2sfdc].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Object "java.lang.String" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException). Message payload is of type: String
Type : org.mule.api.MessagingException
Code : MULE_ERROR--2
Payload : [{phone=772-567-7461, pr_specialist_email=null, sic_code=5211, status=ACTIVE, address1=722 THIRD PLACE, fax=772-567-5054, naics_code=null, client_id=1630, bus_name=HBS INC, address2=null, contact=JANIE LUE, bus_name2=null, country=USA, termination_date=null, state=FL, zip=32962, client_fed_ids={59-1457513}, last_pay_date=2009-11-06, city=VERO BEACH, int_status=Reading}, {phone=713-668-9484, pr_specialist_email=null, sic_code=3714, status=DNE, address1=1140 AVE S, fax=null, naics_code=null, client_id=172, bus_name=FRANK'S SUPPLY OF DALLAS, address2=null, contact=PAM DEL BELLO, bus_name2=null, country=USA, termination_date=null, state=TX, zip=75050, client_fed_ids=null, last_pay_date=null, city=GRAND PRARIE, int_status=Reading}, {phone=(910)854-5000, pr_specialist_email=null, sic_code=null, status=DNE, address1=2720 IMMANUEL ROAD, fax=(910)854-0020, naics_code=null, client_id=2693, bus_name=SCIULLO INTERIOR SYSTEMS, address2=null, contact=Frank Sciullo, bus_name2=null, country=USA, te...
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html
********************************************************************************
Exception stack is:
1. Object "java.lang.String" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException)
org.mule.util.collection.EventToMessageSequenceSplittingStrategy:57 (null)
2. Object "java.lang.String" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}" (java.lang.IllegalArgumentException). Message payload is of type: String (org.mule.api.MessagingException)
org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
********************************************************************************
Root Exception stack trace:
java.lang.IllegalArgumentException: Object "java.lang.String" not of correct type. It must be of type "{interface java.lang.Iterable,interface java.util.Iterator,interface org.mule.routing.MessageSequence,interface java.util.Collection}"
at org.mule.util.collection.EventToMessageSequenceSplittingStrategy.split(EventToMessageSequenceSplittingStrategy.java:57)
at org.mule.util.collection.EventToMessageSequenceSplittingStrategy.split(EventToMessageSequenceSplittingStrategy.java:22)
at org.mule.routing.CollectionSplitter.splitMessageIntoSequence(CollectionSplitter.java:29)
at org.mule.routing.Foreach$CollectionMapSplitter.splitMessageIntoSequence(Foreach.java:245)
at org.mule.routing.outbound.AbstractMessageSequenceSplitter.process(AbstractMessageSequenceSplitter.java:56)
Java file:
public class Db2sfdc {
public List<Map<String, Object>> getPayloadData(#Payload String src){
System.out.println("Src-->"+src);
Map<String, Object> sfdcFields = new HashMap<String, Object>();
List<Map<String, Object>> accountList = new ArrayList<Map<String,Object>>();
sfdcFields.put("ID", "001m000000In0p5AAB");
sfdcFields.put("Current_WSE_Count__c", "20");
accountList.add(sfdcFields);
return accountList ;
}
}
Question:
1)Do I need to use object-to-string-transformer to get the data from db and map in java component?
2) How do I upload/send the data each row from db. When i use for each i am getting above error since I have converted db data to string transformer. I am using java component to transform instead of Data Mapper.
EDIT:
After removing object to string transformer, getting following error at the end, i.e after java mapping:
ERROR 2015-06-17 15:02:09,954 [[psi2sfdc].connector.http.mule.default.receiver.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : java.io.NotSerializableException: org.postgresql.jdbc4.Jdbc4Array (org.apache.commons.lang.SerializationException). Message payload is of type: HttpResponse
Type : org.mule.execution.ResponseDispatchException
Code : MULE_ERROR--2
Payload : org.mule.transport.http.HttpResponse#65b9ccef
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/execution/ResponseDispatchException.html
********************************************************************************
Exception stack is:
1. org.postgresql.jdbc4.Jdbc4Array (java.io.NotSerializableException)
java.io.ObjectOutputStream:1183 (null)
2. java.io.NotSerializableException: org.postgresql.jdbc4.Jdbc4Array (org.apache.commons.lang.SerializationException)
org.apache.commons.lang.SerializationUtils:111 (null)
3. java.io.NotSerializableException: org.postgresql.jdbc4.Jdbc4Array (org.apache.commons.lang.SerializationException). Message payload is of type: HttpResponse (org.mule.execution.ResponseDispatchException)
org.mule.transport.http.HttpMessageProcessTemplate:139 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/execution/ResponseDispatchException.html)
********************************************************************************
Root Exception stack trace:
java.io.NotSerializableException: org.postgresql.jdbc4.Jdbc4Array
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
at org.apache.commons.collections.map.AbstractHashedMap.doWriteObject(AbstractHashedMap.java:1182)
at org.mule.util.CaseInsensitiveHashMap.writeObject(CaseInsensitiveHashMap.java:142)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1495)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1431)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1177)
**
EDIT:2
Solved, after below changes:I have converted to json object after select query as:
<db:select config-ref="PostgreSQL" doc:name="PSI-Select">
<db:parameterized-query><![CDATA[SELECT * FROM clients_int WHERE int_status = 'Reading']]></db:parameterized-query>
</db:select>
<foreach doc:name="For Each">
<json:object-to-json-transformer returnClass="java.lang.Object" doc:name="Object to JSON"/>
<logger message="===Main Flow #[payload]===" level="INFO" doc:name="Logger"/>
</foreach>
Remove the object-to-string-transformer: it transforms the rows enumeration into a String, which prevents for-each to work.
EDIT: Moreover, because the inbound HTTP endpoint is request-response, it will need to return a response to the client. Mule will use the current payload (a Jdbc4Array instance) as the payload of the HTTP response and will fail.
You need to add a set-payload to set the body of the HTTP response to whatever you want to return to the caller. Use an http:response-builder to set response headers, cache directives... as well.
Alternatively, you can switch the HTTP inbound endpoint to one-way. This will return OK to the client immediately, and whether what happens down the flow succeeds or fails.

Not able to access Jira Payload in JAVA (java.util.Arrays$ArrayList)

Here is my Flow information. Trying to GET one issue from JIRA and want to setup that issueID to another project. Here i want to use Custom Transformer and setup all objects using JAVA coding.
<jira:config name="Jira" connectionUser="XXXXXXX" connectionPassword="XXXXX" connectionAddress="http://XXXXXXX/rpc/soap/jirasoapservice-v2" doc:name="Jira">
<jira:connection-pooling-profile initialisationPolicy="INITIALISE_ONE" exhaustedAction="WHEN_EXHAUSTED_GROW"/>
<reconnect count="3"/>
</jira:config>
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="jira-pocFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/input" doc:name="HTTP"/>
<jira:get-issues-from-jql-search config-ref="Jira" jqlSearch="id=MRT-75" maxNumResults="100" doc:name="Jira"/>
<set-variable variableName="payload" value="#[payload[0]]" doc:name="Variable"/>
<component class="JIRATransformer" doc:name="Java"/>
<jira:create-issue-using-object config-ref="Jira" doc:name="Jira" >
<jira:issue ref="#[message.payload]"/>
</jira:create-issue-using-object>
<logger level="INFO" doc:name="Logger"/>
</flow>
I am trying to access JIRA payload object but it's throwing me Error as Type Cast Exception.
#Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws org.mule.api.transformer.TransformerException {
ArrayList<com.atlassian.jira.rpc.soap.beans.RemoteIssue> list = new ArrayList(Arrays.asList(message.getPayload()));
for(RemoteIssue q : (List<RemoteIssue>) list){
System.out.println("Print AssigneeInfo:->"+q.getAssignee());
}
}
I am getting following Errors.
ERROR 2015-04-15 19:58:59,526 [[jira-poc].HTTP_Listener_Configuration.worker.01] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Component that caused exception is: DefaultJavaComponent{jira-pocFlow.component.887693985}. Message payload is of type: Arrays$ArrayList
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. java.util.Arrays$ArrayList cannot be cast to com.atlassian.jira.rpc.soap.beans.RemoteIssue (java.lang.ClassCastException)
JIRATransformer:29 (null)
2. Component that caused exception is: DefaultJavaComponent{jira-pocFlow.component.887693985}. Message payload is of type: Arrays$ArrayList (org.mule.component.ComponentException)
org.mule.component.DefaultComponentLifecycleAdapter:348 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/component/ComponentException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to com.atlassian.jira.rpc.soap.beans.RemoteIssue
at JIRATransformer.transformMessage(JIRATransformer.java:29)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:141)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:69)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
I tried to follow this Documentation URL but couldn't able to figure it out.
http://mulesoft.github.io/jira-connector/java/com/atlassian/jira/rpc/soap/beans/RemoteIssue.html
I want to Access this Payload and want to update some details from payload object here. I can access payload using MEL expression #[payload[0]] and it automatically coverts it to com.atlassian.jira.rpc.soap.beans.RemoteIssue but using Java code i am not able to type cast it.
Can you please help me to cast this object correctly so i can access the Payload here ?
Thanks.
There's a bug in your component.
This Arrays.asList(message.getPayload()) wraps the message payload into a list. But the message payload is already a List<RemoteIssues> so this wrapping is unnecessary.
If you look at the source code of the JIRA connector, you'll see that MuleSoft prefers late casting of the RemoteIssue. I suggest you do the same:
for (Object o : ((List) message.getPayload())) {
RemoteIssue ri = (RemoteIssue) o;
...
}

How to print exception payload within mule message flow

I have a mule flow within which I am logging the entire payload in String format by following code snippet
<logger level="ERROR" message="#[payload:java.lang.String]"/>
Now if the error occurs there really is no need to print the entire payload. The payload object in the message is null and the exception payload is populated with the relevant exception in it.
If I can print just the exception payload in String format, that would suffice. Does any one know how to log the exception payload from the message ?
<logger level="ERROR" message="
#[groovy:message.getExceptionPayload().getRootException().getMessage()]" />
The above code extracts the message related to the cause of exception.
Quite simply:
<logger level="ERROR" message="#[exception]"/>
small correction in the expression use:
[groovy:message.getExceptionPayload().getRootException().getMessage()]
If you want to save error into payload you need to transform it:
%dw 2.0
output application/json
---
{
error: error.detailedDescription,
errorType: (error.errorType.namespace default '') ++ ":" ++ (error.errorType.identifier default '') ,
recoverable: false
}
So, into payload you have your error