How to assert varying payload of connector call in for-each loop in Mule 3 (Munit 1.11)? - mule

My Mule 3.9 app (Munit 1.11) consists of a for-each loop in which a http connector is called in each for-each iteration. The payload with which the connector is called varies in each loop. Now I would like to assert the payload in a corresponding Munit test for each for-each iteration. The idea is to use something comparable to the JavaScript Jest function toHaveBeenNthCalledWith so that a assert payload can be defined for each nth connector call. Is there some build in function for this available or is there a workaround for this?

Related

Parameterizing Header manager in Jmeter for API testing

In J meter I have 2 Thread from Ist thread I am getting token value and I have to use that into 2nd thread header manager. The value generated is in JSON so, I have used JSON extractor to extract the value of that token but I am not able to use that value into Next(2nd Thread)
Thread 1: JSON extractor I have used $..token to extract my token value and stored into a variable 'X' as in JSON Extractor there are one field names of created variables.
Thread 2: Header manager -->> I want to use that value with one word 'YY' so it should be like 'YY (token value)'
For the above one I have tried YY+{X} it's not working for me and also YY {X} it is also not working.
SO kindly help me in this.
First at all, ensure you're running your threads consecutively (Check 'Run Threads Consecutively' in Test Plan properties)
Easiest way to share variables between threads is to use 'Properties', In your example after you have extracted the variable 'X' create an assertion or post processor of your preference(i use beanshell assertion), and copy this: ${__setProperty(paramToAnotherThread,${X})}.
Then in the other thread use ${__property(paramToAnotherThread)} to invoque it.
Hope it works.
Here you can see explained: https://www.blazemeter.com/blog/knit-one-pearl-two-how-use-variables-different-thread-groups

Recursively invoke a Mule flow

Trying to figure out the proper way to recursively invoke a Mule flow.
We have a flow that builds an array of work to do as it runs, then recursively calls itself using a "Flow Reference" inside a "For Each" block. Problem is, we haven't figured out the correct way to pass parameters to this recursive flow, so we're not getting the results we expect.
We tried passing parameters using flow properties (setInvocationParameter() in Groovy), but it seems that these are shared across multiple instances of the flow.
For an example, we have the ForEach array iterating through an array containing [2. 3. 4], but depending on timing, some of these values are lost (we typically see 2, then 4 twice - skipping 3).
We've tried different Mule processing strategies without any luck. Mule's default queued-asynchronous has the issues described above. Synchronous doesn't seem to work at all (makes sense since our recursive model probably requires two instances to run at minimum).
Here's the relevant part of the configuration XML (the entire flow is quite large). At the end of the flow is this:
<foreach collection="#[sessionVars['actionArray']]"
counterVariableName="actionIndex"
rootMessageVariableName="actionVar" doc:name="For Each">
<scripting:component doc:name="Run Each Action">
<scripting:script engine="Groovy">
<![CDATA[def aa = message.getSessionProperty('actionArray')
def this_item = aa.get(message.getInvocationProperty('actionIndex'))
// Pass the desired action for the recursive call
message.setInvocationProperty('FlowAction', this_item)
log.info "Running $this_item" // <- Shows the correct item
return]]>
</scripting:script>
</scripting:component>
<flow-ref name="DoAction" doc:name="Do Action"/>
</foreach>
At the front of the flow, there's a logger that displays the "FlowAction" flow variable. When we test with my [2, 3, 4] array, this logger statement is driven three times (as expected), but usually with values 2, 4 and 4.
We're getting the same results on Mule 3.7 and an older 3.4 system we have (both are the Community Edition).
Thanks for any suggestions from the Mule mavens out there...
I'm not sure this is 100% correct, but here's what we did...
After spending a lot of time trying to get the "For Each" and "Flow reference" approach to work reliably, we gave up and switched to a different technique. Our alternative was to delete the For Each block and drive the flow recursively from a short Groovy script:
. . .
// Invoke the flow recursively for every item in the array
Flow flow = muleContext.getRegistry().lookupFlowConstruct("flow name")
actions.each // actions is an array of integers built earlier
{ item->
MuleMessage msg = message.createInboundMessage()
DefaultMuleSession sess = new DefaultMuleSession(flow, muleContext)
DefaultMuleEvent event = new DefaultMuleEvent(msg, MessageExchangePattern.ONE_WAY, sess)
// Copy the current inbound properties to the new message
message.getInboundPropertyNames().each
{
event.getMessage().setProperty(it, message.getInboundProperty(it), PropertyScope.INBOUND)
}
// Copy the current session variables to the new message too
message.getSessionPropertyNames().each
{
event.setSessionVariable(it, message.getSessionProperty(it))
}
// Now set the item we want processed as a flow variable
event.setFlowVariable("Action", item.toString())
// Finally, trigger the flow (which runs asynchronously)
flow.process(event).getMessage()
}
This is working properly in our environment now.

Count Number of Rows Processed by Mule DataMapper

I am using Mule's datamapper to write data from a database to a csv file. I am using the streaming option on the database, the datamapper and the file ouput. I want to be able to log the amount of records written by the datamapper. Is there a way to get this data? I am running mule server 3.5.2 and have anypoint studio version 5.2.0.
Not out of the box. You can use an outputArgument and increase a counter if you are NOT using streaming.
If you are using streaming then you can pass an input argument of a counter class. And from the script component of Datamapper you can increment the counter and return the counter as part of the payload to get access to it:
<data-mapper:transform config-ref="Pojo_To_JSON_1" doc:name="Pojo To JSON" stream="true">
<data-mapper:input-arguments>
<data-mapper:input-argument key="counter">#[new Counter()]</data-mapper:input-argument>
</data-mapper:input-arguments>
</data-mapper:transform>
Datamapper script:
//MEL
//START -> DO NOT REMOVE
output.__id = input.__id;
//END -> DO NOT REMOVE
output.text = inputArguments.counter.increment();
I know this is an old thread but still below could help -
<byte-array-to-object-transformer doc:name="Byte Array to Object"/>
<set-variable variableName="Orig_Rows" value="#[payload.length]" doc:name="Variable"/>

mule endpoint builder from java code

The below code fetches the global endpoint named SomeInbound and is stored in an invocation variable named someUrl
<set-variable variableName="someUrl" value="#[app.registry['SomeInbound'].getEndpointBuilder().getEndpoint().getUri()]"/>
How can we do the same thing in java(how to get that app object in java and also the other methods following that)
'app' is just a MEL specific context object for accessing parts of the MuleContext etc. In Java you can grab the registry from the MuleContext like so: muleContext.getRegistry() and then use one of the lookup methods to get the object you want.
TO get the muleCOntext, there any many possible ways. Some of which are:
From a test case.
Injection or the #Lookup
annotation:http://www.mulesoft.org/documentation/display/current/Lookup+Annotation
Implementing MuleContextAware:
https://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/context/MuleContextAware.html
Or if you're using a Callable component etc. you can get it from the
MuleEventContext : https://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MuleEventContext.html#getMuleContext()

Mule ESB: How to call a flow inside Datamapper( script)

I have datamapper, ( source: pojo and target:CSV), I need to call the other flow ( or groovy) inside datamapper. I stuck in passing the parameter to the flow. For example, I don't want entire payload has to go to flow for validation. I need to pass only two values. I used
flowRef(String,Object)
output.Item = flowRef("sampletestFlow",input.Model);
It works fine for single payload. But i have to pass one more parameter ( called input.Policy). I know we have to use
flowRef(String,Object,Map).
But it don't know the format for two input parameter.
Could you please anyone help me on this.
I have handled the scenario by the below way. Have create java class and called the java via damapper script. Below is the code inside datamapper script to call the java code.
stringUtil = new com.test.util.StringUtil();
output.style = stringUtil.formatValue(input.RuleStyle);
Hope this helps.