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

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

Related

Issue with Azure Logic APP EPOCH DATE Conversion

I have an issue with epoch date conversion in Azure logic app.
I cannot figure out what I'm doing wrong here.
I have divided my logic app in different steps to first get the Timestamp and remove "/Date" and the trailing "/".
And then I use the add to time function where i am getting an unexpected result.
Input:
"EndDate": "/Date(253402214400000)/",
"StartDate": "/Date(946684800000)/"
Expected output
"EndDate" : "2000-01-01T00:00:00",
"StartDate": "9999-12-31T00:00:00"
Current result:
"EndDate": "1942-11-15T20:26:40.0000000Z",
"StartDate": "2026-10-14T16:21:20.0000000Z"
Logic app code
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"root": {
"CostAccountID": "AD100",
"EndDate": "9999-12-31T00:00:00Z",
"StartDate": "2000-01-01T00:00:00Z"
}
},
"runAfter": {},
"type": "Compose"
},
"Compose_2": {
"inputs": {
"root": {
"CostAccountID": "#{body('Parse_JSON')?['root']?['CostAccountID']}",
"EndDate1": "#{int(replace(replace(body('Parse_JSON')?['root']?['EndDate'],'/Date(',''),')/',''))}",
"StartDate1": "#{int(replace(replace(body('Parse_JSON')?['root']?['StartDate'],'/Date(',''),')/',''))}"
}
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_3": {
"inputs": {
"root": {
"CostAccountID": "#{body('Parse_JSON')?['root']?['CostAccountID']}",
"EndDate": "#{addToTime('1970-01-01T00:00:00Z', int(body('Parse_JSON_2')?['root']?['EndDate1']), 'Second')}",
"StartDate": "#{addToTime('1970-01-01T00:00:00Z', int(body('Parse_JSON_2')?['root']?['StartDate1']), 'Second')}"
}
},
"runAfter": {
"Parse_JSON_2": [
"Succeeded"
]
},
"type": "Compose"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"root": {
"properties": {
"CostAccountID": {
"type": "string"
},
"EndDate": {
"type": "string"
},
"StartDate": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Parse_JSON_2": {
"inputs": {
"content": "#outputs('Compose_2')",
"schema": {
"properties": {
"root": {
"properties": {
"CostAccountID": {
"type": "string"
},
"EndDate1": {
"type": "string"
},
"StartDate1": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Response": {
"inputs": {
"body": "#outputs('Compose_2')",
"statusCode": 200
},
"kind": "http",
"runAfter": {
"Compose_3": [
"Succeeded"
]
},
"type": "Response"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"triggers": {
"manual": {
"inputs": {},
"kind": "Http",
"type": "Request"
}
}
},
"kind": "Stateful"
}
After reproducing from my end, we have observed that you have used the value in milliseconds. Try converting it into seconds and follow the same approach. Below is the code I'm using -
{
"root": {
"CostAccountID": "#{body('Parse_JSON')?['root']?['CostAccountID']}",
"EndDate": "#{addSeconds('1970-01-01T00:00:00Z', div(int(body('Parse_JSON_2')?['root']?['EndDate1']),1000))}",
"StartDate": "#{addSeconds('1970-01-01T00:00:00Z', div(int(body('Parse_JSON_2')?['root']?['StartDate1']),1000))}"
}
}
RESULTS:
I have made changes to your code view. Below is the updated one
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": {
"root": {
"CostAccountID": "AD100",
"EndDate": "/Date(253402214400000)/",
"StartDate": "/Date(946684800000)/"
}
},
"runAfter": {},
"type": "Compose"
},
"Compose_2": {
"inputs": {
"root": {
"CostAccountID": "#{body('Parse_JSON')?['root']?['CostAccountID']}",
"EndDate1": "#{int(replace(replace(body('Parse_JSON')?['root']?['EndDate'],'/Date(',''),')/',''))}",
"StartDate1": "#{int(replace(replace(body('Parse_JSON')?['root']?['StartDate'],'/Date(',''),')/',''))}"
}
},
"runAfter": {
"Parse_JSON": [
"Succeeded"
]
},
"type": "Compose"
},
"Compose_3": {
"inputs": {
"root": {
"CostAccountID": "#{body('Parse_JSON')?['root']?['CostAccountID']}",
"EndDate": "#{addSeconds('1970-01-01T00:00:00Z', div(int(body('Parse_JSON_2')?['root']?['EndDate1']),1000))}",
"StartDate": "#{addSeconds('1970-01-01T00:00:00Z', div(int(body('Parse_JSON_2')?['root']?['StartDate1']),1000))}"
}
},
"runAfter": {
"Parse_JSON_2": [
"Succeeded"
]
},
"type": "Compose"
},
"Parse_JSON": {
"inputs": {
"content": "#outputs('Compose')",
"schema": {
"properties": {
"root": {
"properties": {
"CostAccountID": {
"type": "string"
},
"EndDate": {
"type": "string"
},
"StartDate": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Parse_JSON_2": {
"inputs": {
"content": "#outputs('Compose_2')",
"schema": {
"properties": {
"root": {
"properties": {
"CostAccountID": {
"type": "string"
},
"EndDate1": {
"type": "string"
},
"StartDate1": {
"type": "string"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"Compose_2": [
"Succeeded"
]
},
"type": "ParseJson"
},
"Response": {
"inputs": {
"body": "#outputs('Compose_3')",
"statusCode": 200
},
"kind": "http",
"runAfter": {
"Compose_3": [
"Succeeded"
]
},
"type": "Response"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {},
"triggers": {
"manual": {
"inputs": {},
"kind": "Http",
"type": "Request"
}
}
}
}

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.

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