Implement While and Do While Loop in MuleSoft 4.0

Apisero
4 min readMay 25, 2021

--

Author: Mohammad Mazhar Ansari

All Programming languages like C, C++ and Java have loops like For, While and Do While to handle repeated operation n number of times based on a dataset. However, MuleSoft 4.0 only provides For Each loop. For Each loop on the dataset predefined time based on number of records. In this blog, we will try to learn how we achieve while and do while loop behaviour in MuleSoft.

What is While and Do While Loop?

While and Do While Loop are types of loops which are similar to For loop iterate/repeat but not on a dataset however on conditions.

  • In the ‘while‘ loop the controlling condition appears at the start of the loop.
  • In the ‘do-while‘ loop the controlling condition appears at the end of the loop.

Recursive Function

A recursive function is a function that calls itself during its execution. This enables the function to repeat itself several times, outputting the result in the end of each iteration. Below is an example of a recursive function. Recursive Function must also contain a condition on which it will terminate the calling cycle or else it will run infinitely and can cause Out Of Memory issues.

Implementing Do While Loop in Mule 4.0

We will impede the Do While loop using the recursive call.

  • Go to Project
  • Import below xml as new Mule Configuration File
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<http:request-config name="LocalHostService" doc:name="HTTP Request configuration" doc:id="81ce8454-039f-4dfa-9b5f-ec800fd69d64" >
<http:request-connection protocol="HTTPS" host="localhost" />
</http:request-config>
<flow name="getAllData" doc:id="424a7f40-3912-400b-a06a-6c4e6e8dc109">
<http:listener doc:name="Listener" doc:id="212465ea-f73f-4431-932e-b237651f3289" path="/getAllData" allowedMethods="GET" config-ref="HTTP_Listener_config"/>
<flow-ref doc:name="mainFlow" doc:id="251d9282-69ac-4180-b425-54d091d24245" name="mainFlow" />
</flow>
<sub-flow name="mainFlow" doc:id="5a37075a-5af4-4030-af65-d6ac502a025f" >
<ee:transform doc:name="init count" doc:id="ff54e8aa-b3cc-4be5-9569-9746eeb3174c">
<ee:message>
</ee:message>
<ee:variables>
<ee:set-variable variableName="count"><![CDATA[%dw 2.0
output application/java
---
0]]></ee:set-variable>
</ee:variables>
</ee:transform>
<flow-ref doc:name="getPaginatedData" doc:id="c801ba2e-0164-46c5-8567-03f518399cb4" name="getPaginatedData" />
<logger level="INFO" doc:name="Logger" doc:id="a64c8b87-f1f5-40be-88f2-e0030a893a9d" message="#[payload]"/>
<ee:transform doc:name="payload" doc:id="9ccad799-d777-4484-9d88-4e79fb890226">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output text/plain
---
"Success"]]></ee:set-payload>
</ee:message>
</ee:transform>
</sub-flow>
<sub-flow name="getPaginatedData" doc:id="e00bdae1-e3c0-4d59-9e3a-f42277274264" >
<http:request method="GET" doc:name="getDataByPageNumber" doc:id="4b7801a9-78e4-4027-b135-851ea07cc131" config-ref="LocalHostService" path="/getDataByPageNumber" targetValue="#[read(payload,'application/json')]">
<http:query-params ><![CDATA[#[output application/java
---
{
fromIndex: (vars.count * 200) + 1,
toIndex: (vars.count + 1) * 200
}]]]></http:query-params>
</http:request>
<ee:transform doc:name="isDataPresent" doc:id="4e669d82-f07a-4d4d-ad93-c6127ab15506">
<ee:message>
</ee:message>
<ee:variables>
<ee:set-variable variableName="isDataPresent"><![CDATA[%dw 2.0
output application/java
---
isEmpty(payload..row)]]></ee:set-variable>
</ee:variables>
</ee:transform>
<choice doc:name="Choice" doc:id="070e865e-72a1-46b8-b98e-58ae8f41b0d0" >
<when expression="#[vars.isDataPresent == false]">
<ee:transform doc:name="updateCount and accPayload" doc:id="873dd36c-2f56-48d3-86f7-f7be2ea92b78" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="count" ><![CDATA[%dw 2.0
output application/java
---
vars.count + 1]]></ee:set-variable>
<ee:set-variable variableName="accPayload" ><![CDATA[%dw 2.0
output application/json
---
if (isEmpty(vars.accPayload))
payload.response.result.Candidates.row
else
vars.accPayload ++ payload.response.result.Candidates.row]]></ee:set-variable>
</ee:variables>
</ee:transform>
<flow-ref doc:name="getPaginatedData" doc:id="faac116f-ab7f-4897-b69d-584d242049cd" name="getPaginatedData"/>
</when>
<otherwise >
<ee:transform doc:name="payload" doc:id="17aaa9c5-881b-4622-ada2-dd8557985ca6">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
if (isEmpty(vars.accPayload))
[]
else
vars.accPayload]]></ee:set-payload>
</ee:message>
</ee:transform>
<logger level="INFO" doc:name="Logger" doc:id="78b6b7ed-ebac-4539-8fdd-60d6182573a3" message="#['data not found after iteration: ' ++ (vars.count default &quot;&quot;)]"/>
</otherwise>
</choice>
</sub-flow>
</mule>
  • Get All Data Flow: This Flow calls the main Flow.
  • Main Flow: This Flow initiates pageNumber (count) variable and calls the getPaginatedData flow.
  • Get Paginated Data Flow: Is flow which “getDataByPageNumber”, check if data is present, accumulate the output and call the getPaginatedData Flow in case “getDataByPageNumber” max accepted record else it will terminate the Flow and return all the data to Main Flow.
  • To implement the same in your project just replace “getDataByPageNumber” with your service call. And update “isDataPresent”, “updateCount and accPayload” as per your requirement.

Limitation of this approach

  • MuleSoft restricts the nested call depth to default value of 25 i.e. in case nested call depth reaches beyond 25 MuleSoft throws below exception:

Message: Too many child contexts nested.

Error type: MULE:CRITICAL

To overcome this issue, please set: org.mule.runtime.core.privileged.event.BaseEventContext.maxDepth

Higher than 25 and as per your requirement.

  • As we are accumulating all the data, so it can also cause Memory issues. Keep this point in mind while using this approach.

Scenarios where this can be implemented:

This approach can be used when we don’t know how many records we need to fetch and some looping is not achievable using For Each Loop.

--

--