How to check if condition in foreach using logic app in efficient way? - azure

I have two array variables in for each i compare values one by one abd process further but issue is it is taking to much time for executing when I have 1000 of records.
Variable_1 having around 10 records
Variable_2 which is output if HTTP will have around 1000+ records
Variable_1 =
[
{
"Name": "AAA",
"OwnerId": "121a",
},
{
"Name": "BBB",
"OwnerId": "123b",
},
...
]
and
Variable_2 =
[
{
"Demo_Name": "AAA"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
}
....
]
I have used 2 for each one is forVariable_1and another is forVariable_2``.
and comparing Variable_1.Name == Variable_2.Demo_Name one by one.
so when Variable_2 is having more than 1000+ records it took around a hour to check condition one by one
any solution for this to do it in a fast way?
outer loop is taking around 2h
If I try concurrent execution then increment variable set wrong
values

I tried doing this with Azure Storage Tables as a source for the result, just to see how fast I could iterate through Var2 with 1465 records and Var1 with 9 records. I do it twice here to see just to figure out which way was easiest to do it in. The result here was XXXX matches, the values stored in an Azure Storage Table which I would fetch after the loops were done. I have added a Terminate Action which you could move them before the action For each just to see use one of them for each loop instead of both.
For the record, not sure if this is exactly what you want. Also with this way, if you switch the For each array to loop over Var1 instead of Var2 It was done in less then 10 seconds with all objects. If you make it into different arrays you can filter the two arrays, you can probably use an intersection also. All you need to do is to fetch the records from the Azure Storage Table which is in JSON notation, now with GUIDs as ids.
4 Minutes
This is the flow for the first one of the two loops, the one I like the most, feels cleaner.
Storage Table result which you would need to truncate or something when you are done or something:
You need an Azure Storage Table to offload the results to.
When posting this I reduced Var2 in size as it made no sense in posting 1600 objects.
Code:
{
"$connections": {
"value": {
"azuretables": {
"connectionId": "/subscriptions/*YOUR SUBSCRIPTION ID*/resourceGroups/*RESOURCEGROUP NAME*/providers/Microsoft.Web/connections/azuretables",
"connectionName": "azuretables",
"id": "/subscriptions/*YOUR SUBSCRIPTION ID*/providers/Microsoft.Web/locations/westeurope/managedApis/azuretables"
}
}
},
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each": {
"actions": {
"For_each_2": {
"actions": {
"Condition": {
"actions": {
"Insert_Entity": {
"inputs": {
"body": {
"PartitionKey": "#{items('For_each_2')['Name']}",
"RowKey": "#{guid()}"
},
"host": {
"connection": {
"name": "#parameters('$connections')['azuretables']['connectionId']"
}
},
"method": "post",
"path": "/Tables/#{encodeURIComponent('stackoverflowforeachtmp')}/entities"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"expression": {
"and": [
{
"equals": [
"#items('For_each_2')['Name']",
"#items('For_each')['Demo_Name']"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#variables('TestValueVariable1')",
"runAfter": {
"Set_TestVariable2": [
"Succeeded"
]
},
"runtimeConfiguration": {
"concurrency": {
"repetitions": 50
}
},
"type": "Foreach"
},
"Set_TestVariable1": {
"inputs": {
"name": "TestValueVariable2",
"value": "#{items('For_each')['Demo_Name']}"
},
"runAfter": {},
"type": "SetVariable"
},
"Set_TestVariable2": {
"inputs": {
"name": "TestValueVariable1",
"value": "#variables('Variable 1')"
},
"runAfter": {
"Set_TestVariable1": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"foreach": "#array(variables('Variable 2'))",
"runAfter": {
"For_each_3": [
"Succeeded"
]
},
"runtimeConfiguration": {
"concurrency": {
"repetitions": 50
}
},
"type": "Foreach"
},
"For_each_3": {
"actions": {
"Filter_array": {
"inputs": {
"from": "#array(variables('Variable 1'))",
"where": "#equals(items('For_each_3')['Demo_Name'], item()['Name'])"
},
"runAfter": {},
"type": "Query"
},
"For_each_4": {
"actions": {
"Insert_Entity_2": {
"inputs": {
"body": {
"EvaluationKey": "#{items('For_each_3')['Demo_Name']}-#{items('For_each_4')['Name']}",
"Owner": "#{items('For_each_4')['OwnerId']}",
"PartitionKey": "#{items('For_each_4')['Name']}",
"RowKey": "#{guid()}"
},
"host": {
"connection": {
"name": "#parameters('$connections')['azuretables']['connectionId']"
}
},
"method": "post",
"path": "/Tables/#{encodeURIComponent('stackoverflowforeachtmp')}/entities"
},
"runAfter": {},
"type": "ApiConnection"
}
},
"foreach": "#body('Filter_array')",
"runAfter": {
"Filter_array": [
"Succeeded"
]
},
"type": "Foreach"
}
},
"foreach": "#array(variables('Variable 2'))",
"runAfter": {
"TestValueVariable2": [
"Succeeded"
]
},
"type": "Foreach"
},
"Get_entities": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azuretables']['connectionId']"
}
},
"method": "get",
"path": "/Tables/#{encodeURIComponent('stackoverflowforeachtmp')}/entities"
},
"runAfter": {
"For_each": [
"Succeeded"
]
},
"runtimeConfiguration": {
"paginationPolicy": {
"minimumItemCount": 30000
}
},
"type": "ApiConnection"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "Variable 1",
"type": "Array",
"value": [
{
"Name": "AAA",
"OwnerId": "121a"
},
{
"Name": "BBB",
"OwnerId": "123b"
},
{
"Name": "AAA",
"OwnerId": "123b"
},
{
"Name": "BBB",
"OwnerId": "123b"
},
{
"Name": "FFF",
"OwnerId": "123b"
},
{
"Name": "BBB",
"OwnerId": "123b"
},
{
"Name": "DDD",
"OwnerId": "123b"
},
{
"Name": "CCC",
"OwnerId": "123b"
},
{
"Name": "BBB",
"OwnerId": "123b"
}
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_variable_2": {
"inputs": {
"variables": [
{
"name": "Variable 2",
"type": "Array",
"value": [
{
"Demo_Name": "AAA"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "CCC"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "FFF"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "BBB"
},
{
"Demo_Name": "FFF"
},
{
"Demo_Name": "AAA"
}
]
}
]
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Set_variable": {
"inputs": {
"name": "TestValueVariable2",
"value": "#{length(body('Get_entities')?['value'])}"
},
"runAfter": {
"Terminate": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Terminate": {
"inputs": {
"runStatus": "Succeeded"
},
"runAfter": {
"Get_entities": [
"Succeeded"
]
},
"type": "Terminate"
},
"TestValueVariable1": {
"inputs": {
"variables": [
{
"name": "TestValueVariable1",
"type": "Array"
}
]
},
"runAfter": {
"Initialize_variable_2": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"TestValueVariable2": {
"inputs": {
"variables": [
{
"name": "TestValueVariable2",
"type": "String"
}
]
},
"runAfter": {
"TestValueVariable1": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Month",
"interval": 3
},
"type": "Recurrence"
}
}
}
}

Related

How to get a logic app to stop running after a successful run each day

I have a logic app that I want to run once a line item appears in a table each day. once that line item appear, i don't want the logic app to run anymore that day. Can't quite think of how to accomplish this.
Apart from using the related triggers you can use Terminate action to stop the flow.
After using Get entities (V2) I'm trying to Parse the result to get the timestamp of that particular entity to check if the table has an added row or not for that day
After parsing below is the condition that I'm using
{
"contains": [
"#formatDateTime(body('Parse_JSON')?[0]?['Timestamp'],'dd-MM-yyyy')",
"#formatDateTime(utcNow(),'dd-MM-yyyy')"]
}
Below is the complete flow of my Logic App
RESULTS:
To reproduce the same in your Logic App you can use the below code view
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Condition": {
"actions": {
"Terminate": {
"inputs": {
"runStatus": "Succeeded"
},
"runAfter": {},
"type": "Terminate"
}
},
"else": {
"actions": {
"Delay": {
"inputs": {
"interval": {
"count": 2,
"unit": "Hour"
}
},
"runAfter": {},
"type": "wait"
},
"HTTP": {
"inputs": {
"method": "POST",
"uri": "<URI>"
},
"runAfter": {
"Delay": [
"Succeeded"
]
},
"type": "Http"
}
}
},
"expression": {
"and": [
{
"contains": [
"#formatDateTime(body('Parse_JSON')?[0]?['Timestamp'],'dd-MM-yyyy')",
"#formatDateTime(utcNow(),'dd-MM-yyyy')"
]
}
]
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "If"
},
"Get_entities_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azuretables']['connectionId']"
}
},
"method": "get",
"path": "/v2/storageAccounts/#{encodeURIComponent(encodeURIComponent('AccountNameFromSettings'))}/tables/#{encodeURIComponent('<TableName>')}/entities"
},
"runAfter": {},
"type": "ApiConnection"
},
"Parse_JSON": {
"inputs": {
"content": "#body('Get_entities_(V2)')?['value']",
"schema": {
"items": {
"properties": {
"FirstName": {
"type": "string"
},
"LastName": {
"type": "string"
},
"PartitionKey": {
"type": "string"
},
"RowKey": {
"type": "string"
},
"Timestamp": {
"type": "string"
},
"odata.etag": {
"type": "string"
}
},
"required": [
"odata.etag",
"PartitionKey",
"RowKey",
"Timestamp",
"FirstName",
"LastName"
],
"type": "object"
},
"type": "array"
}
},
"runAfter": {
"Get_entities_(V2)": [
"Succeeded"
]
},
"type": "ParseJson"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"azuretables": {
"connectionId": "/subscriptions/<SUB_ID>/resourceGroups/<RG>/providers/Microsoft.Web/connections/azuretables",
"connectionName": "azuretables",
"id": "/subscriptions/<SUB_ID>/providers/Microsoft.Web/locations/centralus/managedApis/azuretables"
}
}
}
}
}
Alternatively, you can use Recurrence trigger to trigger it in regular intervals with the same logic.

How to monitor the creation of Blob in Azure Storage container/subfolders and Trigger a logic app to send email

We have Azure storage container with subfolders created dynamically, we want to monitor the creation of blob under this container/subfolders and trigger an email once per day with all the blobs added for the day as an attachment in the email.
What we tried is to create a Logic app with Event Grid Trigger (When a resource event occurs) like below.
we would like to know if there is way we can collect all the blobs added in a day under the container and get the contents of all those blobs and add it as an attachment and trigger an email at scheduled time once per day.
Any suggestion on
how to get all the blobs under a container, sub-folder and store the blobs metadata created as an array?
And then how to attach all the blobs created in a single email?
How to get the blob name after, "When a resource event occurs" trigger?
Based on the above requirements, we have created a logic app using timer to list & get the content of all the blob that were created on a particular day & will send an email with the content of the blob as an attachment. using the below work flow code you make the changes as per your business requirement.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Attach": {
"inputs": {
"variables": [
{
"name": "Arraytoattach",
"type": "array"
}
]
},
"runAfter": {
"Lists_blobs_(V2)": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Blob_Name": {
"inputs": {
"variables": [
{
"name": "Count",
"type": "integer",
"value": "#length(variables('Arraytoattach'))"
}
]
},
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"For_each": {
"actions": {
"Compose_2": {
"inputs": "#items('For_each')?['LastModified']",
"runAfter": {},
"type": "Compose"
},
"Compose_3": {
"inputs": "#formatDateTime(outputs('Compose_2'),'yyyy-MM-dd')",
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "Compose"
},
"Condition": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "Arraytoattach",
"value": {
"ContentBytes": "#body('Get_blob_content_(V2)_2')?['$content']",
"Name": "#items('For_each')?['Name']"
}
},
"runAfter": {
"Get_blob_content_(V2)_2": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Get_blob_content_(V2)_2": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('stacklogictest'))}/files/#{encodeURIComponent(encodeURIComponent(items('For_each')?['Path']))}/content",
"queries": {
"inferContentType": true
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"expression": {
"and": [
{
"equals": [
"#outputs('Compose_3')",
"#formatDateTime(utcNow(),'yyyy-MM-dd')"
]
}
]
},
"runAfter": {
"Compose_3": [
"Succeeded"
]
},
"type": "If"
}
},
"foreach": "#body('Lists_blobs_(V2)')?['value']",
"runAfter": {
"Attach": [
"Succeeded"
]
},
"type": "Foreach"
},
"Lists_blobs_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('stacklogictest'))}/foldersV2/#{encodeURIComponent(encodeURIComponent('JTJmdGVzdDEyMw=='))}",
"queries": {
"nextPageMarker": "",
"useFlatListing": false
}
},
"metadata": {
"JTJmdGVzdDEyMw==": "/test123"
},
"runAfter": {},
"type": "ApiConnection"
},
"Send_an_email_(V2)": {
"inputs": {
"body": {
"Attachments": "#variables('Arraytoattach')",
"Body": "<p>Total Number of blob created today : #{variables('Count')}</p>",
"Subject": "Blob created Today",
"To": "<**ReciepientMailAddress**>"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {
"Blob_Name": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Day",
"interval": 1,
"startTime": "2021-07-15T04:00:00Z"
},
"type": "Recurrence"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob": {
"connectionId": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroups>/providers/Microsoft.Web/connections/azureblob",
"connectionName": "azureblob",
"id": "/subscriptions/<subscriptionId>/providers/Microsoft.Web/locations/southindia/managedApis/azureblob"
},
"office365": {
"connectionId": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroups>/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/<subscriptionId>/providers/Microsoft.Web/locations/southindia/managedApis/office365"
}
}
}
}
}
how to get all the blobs under a container, sub-folder and store the blobs metadata created as an array?
Ans: Using the Event Grid you can add all the blob under a particular container to a single array because event grid triggers the logic app when a new blob is added.
And then how to attach all the blobs created in a single email?
Ans: Due to outlook restrictions, we cannot sent or attach the data which excceds more than 25 MB.
3.How to get the blob name after, "When a resource event occurs" trigger?
Ans : As shown in the below image initialize a string variable and add it to the next of event grid event and add the below experssion to get the blob name from the event grid output
first(split(last(split(string(triggerBody()),'/blobs/')),'","event'))
The above logic app will fail if the content type of the blob is text you need make the changes accordingly based on requirement.
Here is the sample output of the above logic app
Created a logic app to send email with attachment of all the blobs inside a container that were added a day before the current day.
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Current_time": {
"inputs": {},
"kind": "CurrentTime",
"runAfter": {
"Lists_blobs_(V2)": [
"Succeeded"
]
},
"type": "Expression"
},
"For_each": {
"actions": {
"For_each_2": {
"actions": {
"Condition": {
"actions": {
"Append_to_array_variable": {
"inputs": {
"name": "attachements",
"value": "#outputs('Compose')"
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "AppendToArrayVariable"
},
"Compose": {
"inputs": {
"ContentBytes": "#{base64(body('Get_Blob'))}",
"Name": "#{last(split(items('For_each_2')?['Path'],'/'))}"
},
"runAfter": {
"Get_Blob": [
"Succeeded"
]
},
"type": "Compose"
},
"Get_Blob": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('<StorageAccountName/connection>'))}/files/#{encodeURIComponent(encodeURIComponent(items('For_each_2')?['Path']))}/content",
"queries": {
"inferContentType": true
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"expression": {
"and": [
{
"greater": [
"#items('For_each_2')?['LastModified']",
"#addDays(body('Current_time'),-1)"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"foreach": "#body('Lists_blobs_(V2)_3')?['value']",
"runAfter": {
"Lists_blobs_(V2)_3": [
"Succeeded"
]
},
"type": "Foreach"
},
"Lists_blobs_(V2)_3": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('<storageaccount connection>'))}/foldersV2/#{encodeURIComponent(encodeURIComponent(items('For_each')?['Path']))}",
"queries": {
"nextPageMarker": "",
"useFlatListing": false
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"foreach": "#body('Lists_blobs_(V2)')?['value']",
"runAfter": {
"Current_time": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "attachements",
"type": "array"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Lists_blobs_(V2)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('<storageaccount connection>'))}/foldersV2/#{encodeURIComponent(encodeURIComponent('JTJmY2FyYm9uYmxh='))}",
"queries": {
"nextPageMarker": "",
"useFlatListing": false
}
},
"metadata": {
"JTJmY2FyYm9uYmxh=": "/<containerName>"
},
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"Send_an_email_(V2)_3": {
"inputs": {
"body": {
"Attachments": "#variables('attachements')",
"Body": "<p>body</p>",
"Subject": "Subject",
"To": "Email"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {
"For_each": [
"Succeeded",
"Failed",
"Skipped",
"TimedOut"
]
},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Day",
"interval": 1,
"schedule": {
"hours": [
"9"
],
"minutes": [
0
]
},
"timeZone": "Standard Time"
},
"type": "Recurrence"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob": {
"connectionId": "/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroup>/providers/Microsoft.Web/connections/azureblob",
"connectionName": "azureblob",
"id": "/subscriptions/<subscriptionId>/providers/Microsoft.Web/locations/<location>/managedApis/azureblob"
},
"office365": {
"connectionId": "/subscriptions/<subscriptionId>/resourceGroups/<ResourceGroup>/providers/Microsoft.Web/connections/office365-1",
"connectionName": "office365",
"id": "/subscriptions/subscriptionId>/providers/Microsoft.Web/locations/<location>/managedApis/office365"
}
}
}
}
}

Azure LogicApps: Conversion from String to Float returns zero

I am surprised to see this, but I witness that in some instance the string value aren't converting as expected to float; mostly returns zero.
The following image shows what happens. As you see I have 2 variables namely var_MarginStr of type string and var_MarginValues of type float in my Logic App. I am assigning var_MarginVal as follows:
var_MarginVal = float(string(variables('var_MarginStr')))
In my working where I trigger my logic app after a new blob is inserted into a blob storage account. The content(*.csv) of the blob is passed to an Azure Function which returns a JSON object. The JSON object is then being looped over each item and is sent to my DB via a Stored Proc.
I have checked my Azure Function which converts the content to JSON working perfectly and the response from such is:
{
"fileName": "20200307-PLC-JKB-Margin.csv",
"agentName": "PLC",
"noOfRecords": 5,
"data": [
{
"accountId": "JKB1234LC",
"marginValue": "0.00"
},
{
"accountId": "JKB4321LC",
"marginValue": "1200000.00"
},
{
"accountId": "JKB5678LC",
"marginValue": "6000000.00"
},
{
"accountId": "JKB8765LC",
"marginValue": "4000000.00"
},
{
"accountId": "JKB9123LC",
"marginValue": "0.00"
}
]
}
Here is my entire LogicApp:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"CSVTOJSON": {
"inputs": {
"body": "#body('Get_blob_content')",
"function": {
"id": "/subscriptions/xxxx/resourceGroups/xxxx-PRD-PORTAL-01/providers/Microsoft.Web/sites/jksbmarginrequest/functions/CSVTOJSON"
},
"method": "POST",
"queries": {
"fileName": "#triggerBody()?['Name']"
}
},
"runAfter": {
"[Initialize]_For_Composed_AccountId": [
"Succeeded"
]
},
"type": "Function"
},
"Condition": {
"actions": {
"Apply_to_DB": {
"actions": {
"Execute_stored_procedure_(V2)": {
"inputs": {
"body": {
"pActualAccountId": "#{items('Apply_to_DB')?['accountId']}#{variables('var_ComposeAccountIdSuffix')}",
"pAgentId": "#variables('var_AgentName')",
"pEffectiveDate": "#{formatDateTime(utcNow(),'yyyy-MM-dd')}",
"pMarginVal": "#variables('var_MarginVal')"
},
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('default'))},#{encodeURIComponent(encodeURIComponent('default'))}/procedures/#{encodeURIComponent(encodeURIComponent('[dbo].[usp_MarginAddUpdate]'))}"
},
"runAfter": {
"[Set]_Margin_Value_Float": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"[Set]_Margin_Value_Float": {
"inputs": {
"name": "var_MarginVal",
"value": "#float(string(variables('var_MarginStr')))"
},
"runAfter": {
"[Set]_Margin_Value_String": [
"Succeeded"
]
},
"type": "SetVariable"
},
"[Set]_Margin_Value_String": {
"inputs": {
"name": "var_MarginStr",
"value": "#items('Apply_to_DB')?['marginValue']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"foreach": "#body('Parse_JSON')?['data']",
"runAfter": {
"For_each": [
"Succeeded"
]
},
"type": "Foreach"
},
"Create_HTML_table": {
"inputs": {
"format": "HTML",
"from": "#body('Parse_JSON')?['data']"
},
"runAfter": {
"Apply_to_DB": [
"Succeeded"
]
},
"type": "Table"
},
"Execute_a_SQL_query_(V2)": {
"inputs": {
"body": {
"actualParameters": {
"pAgentId": "#variables('var_AgentName')"
},
"formalParameters": {
"pAgentId": "VARCHAR(10)"
},
"query": "select * from [dbo].[Parser_MarginFileSettings]\nWhere AgentId =#pAgentId"
},
"host": {
"connection": {
"name": "#parameters('$connections')['sql']['connectionId']"
}
},
"method": "post",
"path": "/v2/datasets/#{encodeURIComponent(encodeURIComponent('default'))},#{encodeURIComponent(encodeURIComponent('default'))}/query/sql"
},
"runAfter": {
"[Set]_Agent_Name": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"For_each": {
"actions": {
"[Set]_Composed_Account_ID_with_Suffix": {
"inputs": {
"name": "var_ComposeAccountIdSuffix",
"value": "#items('For_each')?['Suffix_AccountId']"
},
"runAfter": {},
"type": "SetVariable"
}
},
"foreach": "#body('Execute_a_SQL_query_(V2)')?['resultsets']?['Table1']",
"runAfter": {
"Execute_a_SQL_query_(V2)": [
"Succeeded"
]
},
"type": "Foreach"
},
"Parse_JSON": {
"inputs": {
"content": "#body('CSVTOJSON')",
"schema": {
"properties": {
"agentName": {
"type": "string"
},
"data": {
"items": {
"properties": {
"accountId": {
"type": "string"
},
"marginValue": {
"type": "string"
}
},
"required": [
"accountId",
"marginValue"
],
"type": "object"
},
"type": "array"
},
"fileName": {
"type": "string"
},
"noOfRecords": {
"type": "integer"
}
},
"type": "object"
}
},
"runAfter": {},
"type": "ParseJson"
},
"[Set]_Agent_Name": {
"inputs": {
"name": "var_AgentName",
"value": "#body('Parse_JSON')?['agentName']"
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"else": {
"actions": {
"Compose_Fail-over_Data": {
"inputs": {
"File_Name": "#triggerBody()?['Name']",
"Message": "#body('CSVTOJSON')",
"Status_Code": "#outputs('CSVTOJSON')['statusCode']"
},
"runAfter": {},
"type": "Compose"
},
"For_Error_Listing": {
"inputs": {
"format": "HTML",
"from": "#outputs('Compose_Fail-over_Data')"
},
"runAfter": {
"Compose_Fail-over_Data": [
"Succeeded"
]
},
"type": "Table"
},
"Send_an_email_(V2)": {
"inputs": {
"body": {
"Body": "<p><u><strong>An Error Occured While Updating Margin Request File<br>\n<br>\n</strong></u><u><strong>#{outputs('Compose_Fail-over_Data')}</strong></u><u><strong></strong></u><br>\n</p>",
"Subject": "Margin File Output",
"To": "itops#jkstock.keells.com"
},
"host": {
"connection": {
"name": "#parameters('$connections')['office365']['connectionId']"
}
},
"method": "post",
"path": "/v2/Mail"
},
"runAfter": {
"For_Error_Listing": [
"Succeeded"
]
},
"type": "ApiConnection"
}
}
},
"expression": {
"and": [
{
"equals": [
"#outputs('CSVTOJSON')['statusCode']",
200
]
}
]
},
"runAfter": {
"CSVTOJSON": [
"Succeeded"
]
},
"type": "If"
},
"Get_blob_content": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/datasets/default/files/#{encodeURIComponent(encodeURIComponent(triggerBody()?['Path']))}/content",
"queries": {
"inferContentType": true
}
},
"runAfter": {},
"runtimeConfiguration": {
"staticResult": {
"name": "Get_blob_content0",
"staticResultOptions": "Disabled"
}
},
"type": "ApiConnection"
},
"[Initialize]_Agent_Name": {
"inputs": {
"variables": [
{
"name": "var_AgentName",
"type": "string",
"value": "PLC"
}
]
},
"runAfter": {
"Get_blob_content": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"[Initialize]_For_Composed_AccountId": {
"inputs": {
"variables": [
{
"name": "var_ComposeAccountIdSuffix",
"type": "string"
}
]
},
"runAfter": {
"[Initialize]_For_Margin_Value_FLoat": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"[Initialize]_For_Margin_Value_FLoat": {
"inputs": {
"variables": [
{
"name": "var_MarginVal",
"type": "float",
"value": 0
}
]
},
"runAfter": {
"[Initialize]_Margin_Value_String": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"[Initialize]_Margin_Value_String": {
"inputs": {
"variables": [
{
"name": "var_MarginStr",
"type": "string"
}
]
},
"runAfter": {
"[Initialize]_Agent_Name": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"staticResults": {
"Get_blob_content0": {
"outputs": {
"headers": {},
"statusCode": "OK"
},
"status": "Succeeded"
}
},
"triggers": {
"When_a_blob_is_added_or_modified_(properties_only)": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['azureblob']['connectionId']"
}
},
"method": "get",
"path": "/datasets/default/triggers/batch/onupdatedfile",
"queries": {
"folderId": "JTJmcGxj",
"maxFileCount": 1
}
},
"metadata": {
"JTJmcGxj": "/plc"
},
"recurrence": {
"frequency": "Second",
"interval": 3
},
"splitOn": "#triggerBody()",
"type": "ApiConnection"
}
}
},
"parameters": {
"$connections": {
"value": {
"azureblob": {
"connectionId": "/subscriptions/xxxx/resourceGroups/xxx-PRD-PORTAL-01/providers/Microsoft.Web/connections/azureblob-2",
"connectionName": "azureblob-2",
"id": "/subscriptions/xxxx/providers/Microsoft.Web/locations/southeastasia/managedApis/azureblob"
},
"office365": {
"connectionId": "/subscriptions/xxxx/resourceGroups/xxx-PRD-PORTAL-01/providers/Microsoft.Web/connections/office365",
"connectionName": "office365",
"id": "/subscriptions/xxxx/providers/Microsoft.Web/locations/southeastasia/managedApis/office365"
},
"sql": {
"connectionId": "/subscriptions/xxxx/resourceGroups/xxx-PRD-PORTAL-01/providers/Microsoft.Web/connections/sql-6",
"connectionName": "sql-6",
"id": "/subscriptions/xxxx/providers/Microsoft.Web/locations/southeastasia/managedApis/sql"
}
}
}
}
}
When a For Each runs by default it runs iterations concurrently. The variables are not guaranteed to use the value for the current iteration. If you change the For Each to run sequentially it will work with the variables. In the For Each settings turn on Concurrency Control and set the Degree of Parallelism to 1. The other option is to remove the use of variables in the loop if you want it to run in parallel.
The Microsoft documentation for loop on this page https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-control-flow-loops says
To get predictable results from operations on variables during each
loop iteration, run those loops sequentially. For example, when a
concurrently running loop ends, the increment, decrement, and append
to variable operations return predictable results. However, during
each iteration in the concurrently running loop, these operations
might return unpredictable results.

Unable to set value to variable it always take initial value in logic app

I have one variable I set a default value as 0.
In for_each I'm setting new value to startIndex variable and use that variable in For_each but still it is using old 0 value.
logic app code -
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"For_each_2": {
"actions": {
"Set_variable_3": {
"inputs": {
"name": "output",
"value": "#{split(items('For_each_2'),':')[0]}:#{substring(variables('mydata'),variables('startindex'),int(split(items('For_each_2'),':')[1]))}"
},
"runAfter": {},
"type": "SetVariable"
},
"Set_variable_4": {
"inputs": {
"name": "startIndex",
"value": "#int(split(items('For_each_2'),':')[1])"
},
"runAfter": {
"Set_variable_3": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"foreach": "#variables('splitvar')",
"runAfter": {
"Initialize_variable_9": [
"Succeeded"
]
},
"type": "Foreach"
},
"Initialize_variable_5": {
"inputs": {
"variables": [
{
"name": "mydata",
"type": "String",
"value": "abcdefg"
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Initialize_variable_6": {
"inputs": {
"variables": [
{
"name": "key",
"type": "String",
"value": "AA:3;BB:2"
}
]
},
"runAfter": {
"Initialize_variable_5": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_7": {
"inputs": {
"variables": [
{
"name": "splitvar",
"type": "Array",
"value": "#split(variables('key'),';')"
}
]
},
"runAfter": {
"Initialize_variable_6": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_8": {
"inputs": {
"variables": [
{
"name": "output",
"type": "String"
}
]
},
"runAfter": {
"Initialize_variable_7": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Initialize_variable_9": {
"inputs": {
"variables": [
{
"name": "startIndex",
"type": "Integer",
"value": 0
}
]
},
"runAfter": {
"Initialize_variable_8": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
}
}
You need to enable concurrency control on the for each action. As default the for each action run with a Degree of Parallelism set to 20. So it runs the action 20 times in parallel as the default behavior. Turn it down to 1.
]2

Randomize list in Azure Logic Apps

Is it possible to randomize the elements of an array using just functions from WDL in Logic apps?
Let's imagine you have array from 1 to 10
You create one lement randomized array variable
first(variables('Array'))
And a temp value (tempValue) and temp array (temp) (used in later steps because self referencing is not allowed)
Then you create until loop like so
With Until condition being
equals(length(variables('Randomized')), length(variables('Array')))
Calculate random index tempValue in array (random index at which we will split array)
rand(0,sub(length('Randomized'),1))
And combine new array temp by inserting current iteration value at random place
union(
take(
variables('Randomized'),
variables('tempInteger')
),
array(variables('Array')[add(iterationIndexes('Until'),1)]),
skip(
variables('Randomized'),
variables('tempInteger')
)
)
And after condition statement set randomized variable to temp value
Which after the last iteration will net you randomized input table
And full code example
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Init_Randomized_One_Element_Array": {
"inputs": {
"variables": [
{
"name": "Randomized",
"type": "Array",
"value": [
"#first(variables('Array'))"
]
}
]
},
"runAfter": {
"Init_Unrandomized_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Init_Randomized_Temp_Array": {
"inputs": {
"variables": [
{
"name": "temp",
"type": "Array"
}
]
},
"runAfter": {
"Init_Randomized_One_Element_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Init_Temp_Calculated_Value": {
"inputs": {
"variables": [
{
"name": "tempInteger",
"type": "integer"
}
]
},
"runAfter": {
"Init_Randomized_Temp_Array": [
"Succeeded"
]
},
"type": "InitializeVariable"
},
"Init_Unrandomized_Array": {
"inputs": {
"variables": [
{
"name": "Array",
"type": "Array",
"value": [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
]
}
]
},
"runAfter": {},
"type": "InitializeVariable"
},
"Until": {
"actions": {
"Add_random_element_to_temp_array": {
"inputs": {
"name": "temp",
"value": "#union(\r\n\ttake(\r\n\t\t variables('Randomized'),\r\n\t\t variables('tempInteger')\r\n\t),\r\n\tarray(variables('Array')[add(iterationIndexes('Until'),1)]),\r\n\tskip(\r\n\t variables('Randomized'),\r\n\t variables('tempInteger')\r\n\t)\r\n)\r\n"
},
"runAfter": {
"Random_Index_to_insert": [
"Succeeded"
]
},
"type": "SetVariable"
},
"Random_Index_to_insert": {
"inputs": {
"name": "tempInteger",
"value": "#rand(0,sub(length('Randomized'),1))"
},
"runAfter": {},
"type": "SetVariable"
},
"Set_randomized_from_temp": {
"inputs": {
"name": "Randomized",
"value": "#variables('temp')"
},
"runAfter": {
"Add_random_element_to_temp_array": [
"Succeeded"
]
},
"type": "SetVariable"
}
},
"expression": "#equals(length(variables('Randomized')), length(variables('Array')))",
"limit": {
"count": 60,
"timeout": "PT1H"
},
"runAfter": {
"Init_Temp_Calculated_Value": [
"Succeeded"
]
},
"type": "Until"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
}
}
There is no direct way to randomize anything in a LogicApp.
I suppose you could come up with some pattern that could pseudorandomize a list entirely within a Logic App, but....
The more 'correct' way to handle this would be with a Function.

Resources