Session Variable not available in FlowRef Lookup Table - mule

I am using a Message Enricher to call a web services and return what a part number is for the external data source. I am saving that payload into a Session Variable. I am then using a Lookup Table from within a Datamapper to send the current payloads' part number to be referenced against the external data source (using xpath). I am able to invoke the Lookup and pass the local variable but the payload that was saved into the Session Variable is not being passed through to the Lookup Flow, so my xpath query will not work.
Here is the Session Variable and Datamapper
<flow>
<enricher target="#[sessionVars['SesVar']]" doc:name="Message Enricher">
<flow-ref name="query-line-details-erpFlow" doc:name="query-line-details-erpFlow"/>
</enricher>
<logger message="Session Var: #[sessionVars['SesVar']]" level="INFO" doc:name="Logger"/>
<data-mapper:transform config-ref="XML_To_XML" doc:name="XML To XML"/>
</flow>
Here is the Lookup Table logic
output.ExternalPart = (isnull(lookup(LookUpPart).get([input.LocalPart])) ? null : lookup(LookUpPart).get([input.LocalPart]).ExternalPart);
Finally here is the second flow where the Session Var should be accessed from
<flow>
<logger message="Spit out the var #[sessionVars.SesVar]" level="INFO" doc:name="Logger"/>
</flow>
From what research I have done, the Session Variable is not passing a Transport Barrier so it should be able to be referenced from this scope. I have also tried with flowVars also.
Any help would be greatly appreciated.

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.

Mule-Unable to access Session Variable value in another flow

I need to retrieve the value set in session variable in flow1 to flow2. The code I've written looks like this :
<flow name="demo1Flow">
<http:listener config-ref="HTTP_Listener_Configuration" path="demo" doc:name="HTTP"/>
<set-session-variable variableName="name" value="balwant" doc:name="Session Variable"/>
<logger message="Inside demo1 #[sessionVars.name]" level="INFO" doc:name="Logger"/>
<http:request config-ref="HTTP_Request_Configuration" path="/test" method="GET" doc:name="HTTP"/>
</flow>
<flow name="demoFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<logger message="Inside demo flow #[sessionVars['name']]" level="INFO" doc:name="Logger"/>
</flow>
With the above code I'm not able to get the value from session variable which was set in demo1Flow to demoFlow. The output for this flow I'm getting is :
INFO 2017-03-07 12:55:28,455 [[demo].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: Inside demo1 balwant
INFO 2017-03-07 12:55:28,536 [[demo].HTTP_Listener_Configuration.worker.02] org.mule.api.processor.LoggerMessageProcessor: Inside demo flow null.
As the documentation says that value in Session variable is accessible across the session in different flows, but here that is not happening :(. Not sure what is the reason.
Referring Session Variable Transformer Reference documentation, the Session Variable persist for the entire message lifecycle, regardless of transport barriers, except for the HTTP Connector which doesn’t propagate them.
They are two independent flows which process messages based on different input paths, although you are calling using http requester from flow1,second has its own scope.
For every flow it's scope begins with its inbound.
As there is no relationship between those two flows, you can't access anything from flow1 in the other. If you want that variable you can set as outbound property then it will become inbound property to the second flow. Otherwise you can set as uri parameters.
Regards,
Mallesh

Mule getting data from ConsumerIterator

My mule flow is:
<sfdc:query config-ref="SFDC__DevInt" query="dsql:SELECT Id FROM Account WHERE Name = #[flowVars.Name]" doc:name="Salesforce"/>
<logger message="Select query: #[message.payload]" level="INFO" doc:name="Logger"/>
<foreach doc:name="For Each">
<logger message="#[message.payload]" level="INFO" doc:name="Logger"/>
<logger message="#[message.payload.Id]" level="INFO" doc:name="Logger"/>
</foreach>
Above for loops returns the id. Instead of looping is there any direct way of getting data as iterator object? i.e I need to get the value of id.
Data inside for loops returns:
SFDC:Select query: org.mule.streaming.ConsumerIterator#2f23abf
INFO 2015-06-22 13:10:25,520
{Id=0011100000uPbqeAAC, type=Account}
At a time I will be getting single data.
I tried with #[message.payload.iterator().hasNext().next()], but getting
Message : Execution of the expression "message.payload.iterator().hasNext().next()" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: ConsumerIterator
Code : MULE_ERROR--2
The message payload after sfdc:query is an instance of org.mule.streaming.ConsumerIterator, which implements java.util.Iterator. Therefore there's no reason to call iterator() on it, it is already an iterator.
Moreover hasNext returns a boolean, not an Iterator instance, so you can't chain the calls as you did.
Your expression should thus be:
#[message.payload.hasNext() ? message.payload.next() : null]
assuming that null is the value you want in case the enumeration is empty.
You can also convert the iterator into a list if you need to use for-each
#[org.apache.commons.collections.IteratorUtils.toList(payload)]

Mule MEL to read database result-set from an second 'database outbound endpoint'

I have a flow something like this
A 'Database inbound endpoint' which polls(for every 5 mins) to mySQL Database-Server and get result-set by a select-query (automatically this becomes the current payload i.e #[message.payload])
'For each' component and a 'Logger' component in it using a expression as #[message.payload]
Now flow has one more 'Database-out-bound-endpoint' component which executes another select-query and obtains result-set.
'For each' component with a 'Logger' component in it using a expression as #[message.payload]
Note: in the loggers result-set of first DB is printing. I mean second logger is also showing result-set of first query itself.Because the result-set is storing as payload
so, my questions are
what is the MEL to read the result-set of second database-query in the above scenario.
is there any another way to read result-set in the flow
Here is the configuration XML
<jdbc-ee:connector name="oracle_database" dataSource-ref="Oracle_Data_Source" validateConnections="true" queryTimeout="-1" pollingFrequency="0" doc:name="Database"/>
<flow name="testFileSaveFlow3" doc:name="testFileSaveFlow3">
<poll frequency="1000" doc:name="Poll">
<jdbc-ee:outbound-endpoint exchange-pattern="one-way" queryKey="selectTable1" queryTimeout="-1" connector-ref="oracle_database" doc:name="get data from table 1">
<jdbc-ee:query key="selectTable1" value="SELECT * FROM TABLE1"/>
</jdbc-ee:outbound-endpoint>
</poll>
<foreach doc:name="For Each">
<logger message="#[message.payload]" level="INFO" doc:name="prints result-set of table1"/>
</foreach>
<jdbc-ee:outbound-endpoint exchange-pattern="one-way" queryKey="selectTable2" queryTimeout="-1" connector-ref="oracle_database" doc:name="get data from table 2">
<jdbc-ee:query key="selectTable2" value="SELECT * FROM TABLE2"/>
</jdbc-ee:outbound-endpoint>
<foreach doc:name="For Each">
<logger message="#[message.payload]" level="INFO" doc:name="prints result-set of table2"/>
</foreach>
</flow>
thanks in advance.
This is not the issue with the MEL. It is the issue with your flow logic.
The second result set is not available in the message.
The JDBC Outbound Endpoint is one-way. So Mule flow will not wait for the reply (result set) from the second JDBC (outbound ) in the middle of the flow. So the second time also it is printing the first result set.
Type 1:
Try making your JBDC outbound request-response instead of one-way.
Type 2:
Try Mule Enricher to call the JDBC outbound to call the DB and store the result set into a varaible and try looping the varaible.
Hope this helps.

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.