Logic App - HTTP Action - Loop until 200 - azure

I have a logic app with an http action.
As the reply policy allows at most 4 retries I put the activity inside a do-until loop (with max count and timeout) using the http status code as escape variable (until it is 200).
This image should make this more clear
At runtime I get this error
[EDIT]InvalidTemplate. Unable to process template language expressions for action 'HTTPAction'[EDIT]: Unable to process template language expressions for action 'HttpAction' [..] The template language expression 'equals(outputs('HttpAction')['statusCode'], 200)' cannot be evaluated because property 'statusCode' cannot be selected.
Any hints?
Thanks, Alessandro
[EDIT]The http request just works (tried with fiddler), in the workflow i suppose it just doesn't get executed due to the template error (why does it fail at runtime and not in edit mode?)[EDIT]

Going to reply for readable code.
I just made a quick POC to simulate your scenario, but I can't reproduce your issue.
Code of my Do-Until:
"Until": {
"actions": {
"HttpGetMyValues": {
"inputs": {
"headers": {
"Ocp-Apim-Subscription-Key": "#parameters('OcpApimSubscriptionKey')"
},
"method": "GET",
"uri": "https://myendpointuri"
},
"runAfter": {},
"type": "Http"
}
},
"expression": "#equals(outputs('HttpGetMyValues')['statusCode'], 200)",
"limit": {
"count": 1,
"timeout": "PT1M"
},
"runAfter": {},
"type": "Until"
}
I can save and run the Logic App without problems.

Retry policy is configurable, currently only available via code view, but we plan to enable it in designer very soon. Here's the documentation.
"retryPolicy" : {
"type": "<type-of-retry-policy>",
"interval": <retry-interval>,
"count": <number-of-retry-attempts>
}

I know this is late to the game, but the error is due to the condition that ends the 'do-until' loop being contained within the loop itself. You'll need to use a value that is outside of the loop as reference. I suggest:
Creating a variable before the 'do-until' action with the default value as '400'
Using the variable as the value the 'Status code' value needs to equal
Updating (set-variable in Logic Apps) the variable at the end of each loop iteration to equal the 'Status code'.

In the Until control:
Click Edit Advanced Mode
Replace the text with #equals(actions('HTTPAction').status, 'Succeeded')
The code means stop do until loop when the HTTPAction has completed

Related

Azure Logic App : how to trigger logic app workflow 2000+ times?

"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"runtimeConfiguration": {
"concurrency": {
"maximumWaitingRuns": 99,
"runs": 1
}
},
"type": "Request"
}
}
From the above code can I increase the trigger amount from "maximumWaitingRuns": 99 to 2000+?
If yes then how?
I also want to trigger it 2000+ times using single click.
One of the workaround to make the workflow run multiple times is to use a recurrence trigger instead of an HTTP trigger.
Another workaround would be mentioning the iterations and run the workflow through Postman. After saving your request to one of your collections, navigate to your collection >> Run >> Mention the number of iterations >> Run Sample.

Forge-Get Item Path along with custom attributes in BIM360 document

Two Requirements are needed:
Get item path of the document in a BIM360 document management.
Get all custom attributes for that item.
For Req. 1, an api exists to fetch and for getting custom attributes, another api exists and data can be retrived.
Is there a way to get both the requirements in a single api call instead of using two.
In case of large number of records, api to retrieve item path is taking more than an hour for fetching 19000+ records and token gets expired though refesh token is used, while custom attribute api processes data in batches of 50, which completes it in 5 minutes only.
Please suggest.
Batch-Get Custom Attributes is for the additional attributes of Document Management specific. While path in project is a general information with Data Management.
The Data Management API provides some endpoints in a format of command, which can ask the backend to process the data for bunch of items.
https://forge.autodesk.com/en/docs/data/v2/reference/http/ListItems/
This command will retrieve metadata for up to 50 specified items one time. It also supports the flag includePathInProject, but the usage is tricky and API document does not indicate it. In the response, it will tell the pathInProject of these items. It may save more time than iteration.
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "commands",
"attributes": {
"extension": {
"type": "commands:autodesk.core:ListItems",
"version": "1.0.0" ,
"data":{
"includePathInProject":true
}
}
},
"relationships": {
"resources": {
"data": [
{
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:vkLfPabPTealtEYoXU6m7w"
},
{
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:bcg7gqZ6RfG4BoipBe3VEQ"
}
]
}
}
}
}
Get item path of the document in a BIM360 document management.
Is this question about getting the hiarchy of the item? e.g. rootfolder>>subfolder>>item ? With the endpoint, by specifying the query param includePathInProject=true, it will return the relative path of the item (pathInProject) in the folder structure.
https://forge.autodesk.com/en/docs/data/v2/reference/http/projects-project_id-items-item_id-GET/
"data": {
"type": "items",
"id": "urn:adsk.wipprod:dm.lineage:xxx",
"attributes": {
"displayName": "my-issue-att.png",
"createTime": "2021-03-12T04:51:01.0000000Z",
"createUserId": "xxx",
"createUserName": "Xiaodong Liang",
"lastModifiedTime": "2021-03-12T04:51:02.0000000Z",
"lastModifiedUserId": "200902260532621",
"lastModifiedUserName": "Xiaodong Liang",
"hidden": false,
"reserved": false,
"extension": {
"type": "items:autodesk.bim360:File",
"version": "1.0",
"schema": {
"href": "https://developer.api.autodesk.com/schema/v1/versions/items:autodesk.bim360:File-1.0"
},
"data": {
"sourceFileName": "my-issue-att.png"
}
},
"pathInProject": "/Project Files"
}
or if you may iterate by the data of parent
"parent": {
"data": {
"type": "folders",
"id": "urn:adsk.wipprod:fs.folder:co.sdfedf8wef"
},
"links": {
"related": {
"href": "https://developer.api.autodesk.com/data/v1/projects/b.project.id.xyz/items/urn:adsk.wipprod:dm.lineage:hC6k4hndRWaeIVhIjvHu8w/parent"
}
}
},
Get all custom attributes for that item. For Req. 1, an api exists to fetch and for getting custom attributes, another api exists and data can be retrived. Is there a way to get both the requirements in a single api call instead of using two. In case of large number of records, api to retrieve item path is taking more than an hour for fetching 19000+ records and token gets expired though refesh token is used, while custom attribute api processes data in batches of 50, which completes it in 5 minutes only. Please suggest.*
Let me try to understand the question better. Firstly, two things: Custom Attributes Definitions, and Custom Attributes Values(with the documents). Could you clarify what are they with 19000+ records?
If Custom Attributes Definitions, the API to fetch them is
https://forge.autodesk.com/en/docs/bim360/v1/reference/http/document-management-custom-attribute-definitions-GET/
It supports to set limit of each call. i.e. the max limit of one call is 200, which means you can fetch 19000+ records by 95 times, while each time calling should be quick (with my experience < 10 seconds). Totally around 15 minutes, instead of more than 1 hour..
Or at your side, each call with 200 records will take much time?
If Custom Attributes Values, the API to fetch them is
https://forge.autodesk.com/en/docs/bim360/v1/reference/http/document-management-versionsbatch-get-POST/
as you know, 50 records each time. And it seems it is pretty quick at your side with 5 minutes only if fetch the values of 19000+ records?

Simple filter in Service Bus Rule not working

I have a really simple requirement to setup a rule on a subscription so that if priority is LOW a message is picked up. I didnt expect this to be difficult to do and it just doesnt work
My message is below
{
"messageId": "90db0000-d0ef-aeb6-cb37-08d86a2d0015",
"conversationId": "90db0000-d0ef-aeb6-6512-08d86a2d0018",
"sourceAddress": "ADDRESS",
"destinationAddress": "sb://MYBUS.servicebus.windows.net/my-topic",
"messageType": [
"urn:message:Messaging.Services.Models:MyMessage"
],
"message": {
"messageIdentifier": "f79345cb-ce6a-445c-85b6-d8003eb52046",
"priority": "LOW"
},
"sentTime": "2020-10-06T19:21:18.0426039Z",
"headers": {},
"host": {
"machineName": "MACHINE",
"processName": "Application",
"processId": 27640,
"assembly": "Application",
"assemblyVersion": "1.0.0.0",
"frameworkVersion": "3.1.8",
"massTransitVersion": "7.0.4.0",
"operatingSystemVersion": "Microsoft Windows NT 6.2.9200.0"
}
}
I thought that the syntax is as simple as message.priority = "LOW"?
I then tried creating a rule against the message body itself, filtering on destinationAddress, that didnt pick up any messages either
This is really frustrating please can someone help?
I am using Service Bus Explorer
Paul
Agree with the previous answer.
From the MS Docs > All filters evaluate message properties. Filters can't evaluate the message body.
See here : https://learn.microsoft.com/en-us/azure/service-bus-messaging/topic-filters
Azure Service Bus filters operate on headers/properties and cannot access the message body/payload. You'd need to promote the message:priority into the header.

Azure data factory pipeline: conditional checking on variable activity

I have a web activity to call a REST API and save it output into a table. But one of its value will not available always. So we need to do a conditional checking while setting its output into a variable activity.
you can see how we have done that in the variable activity.
This is the rest APIs output.
{
"value": {
"id": "464a115fd3cb",
"runId": "464a115fd3cb",
"parameters": {},
"invokedBy": {
"id": "99448303872CU28",
"name": "TRIGGER_TIMESHEET_API",
"invokedByType": "ScheduleTrigger"
},
"isLatest": true
},
"continuationToken": "+RID:~sj5QALRCCB4w5hYAAAAADQ",
"ADFWebActivityResponseHeaders": {
"Pragma": "no-cache"
}
}
Here "continuationToken" will not be a part of all the API responses. So if this value is available in the API response, we need to set that in the variable activity.
In the attached screenshot, you can see that we are setting the variable. But if that key is not available in the API response, it will throw an error.
So we are looking for a solution to check whether that key is existing in the JSON output.
Any help appreciated.
I think you almost get your goal already,please use Set Variable Activity and If-Condition Activity:
Set Variable Activity:
If-Condition Activity to judge the name is empty or not:
Then you could configure the True Activity and False Activity:

Azure Logic App: How to save HTTP Connector's body content to OneDrive file?

I have a simple Azure Logic App with the following components:
Recurrence
HTTP Get from HTTPS url
I've tried to configure the next component to save the HTTP response body to OneDrive with OneDrive Connector configured as follows:
FilePath: ApiTest/test.json
Content: #{body('http')}
Content Transfer Encoding: None
This gives the following error:
{"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'microsoftonedriveconnector' inputs at line '1' and column '11': 'Template language expression cannot be evaluated: one of string interpolation segment value has unsupported type 'Object'. Please convert the value to string using the 'string()' function.'."}
If I then use #{string(body('http'))} I get:
{"code":"InvalidTemplate","message":"Unable to process template language expressions in action 'microsoftonedriveconnector' inputs at line '1' and column '11': 'The template language function 'string' was invoked with an invalid parameter. The value cannot be converted to the target type.'."}
How can I use the body of HTTP Connector and save it to One Drive?
I don't have an answer, but I am wrestling with this very issue right now. I will post if I find a solution and would be very interested in case any one else finds a solution. I do find one thing interesting. There is a header and body option on the consuming end of my Http Connector which works when it runs. The error (as the above poster notes) occurs when passing that value to the next card. But, when I look at the output (link) on the run tab, I see a json value for the header and for the body. Does this need to be wrapped in a json parser?
This works for me just fine and generated the file in the /random/test.txt folder, however I believe the problem in your case is that you are downloading a JSON file which is causing it to be interpreted as an object by the engine.
I'll follow up with the team and maybe we need a "ToJson" call, or a way to "Passthrough", or make "String" more "flexible" (though that could be weird).
"fileContent": {
"Content": "#{body('http')}",
"ContentTransferEncoding": "None"
},
Actions in code view looks like:
"http": {
"type": "Http",
"inputs": {
"method": "GET",
"uri": "http://www.carlosag.net/"
},
"conditions": []
},
"microsoftonedriveconnector": {
"type": "ApiApp",
"inputs": {
"apiVersion": "2015-01-14",
"host": {
"id": "/subscriptions/xxx/resourceGroups/zzz/providers/Microsoft.AppService/apiApps/MicrosoftOneDriveConnector",
"gateway": "https://yyy.azurewebsites.net"
},
"operation": "UploadFile",
"parameters": {
"filePath": "random/test.json",
"fileContent": {
"Content": "#{body('http')}",
"ContentTransferEncoding": "None"
},
"overwrite": true
},
"authentication": {
"type": "Raw",
"scheme": "Zumo",
"parameter": "#parameters('/subscriptions/...')"
}
},
You should try "#body('http')". I believe this will work. "#{body('http')}" is a form of string interpolation: expected output value is string and not a JSON.
I initialized a String variable 'Content' and set the value to the body of the HTTP.
#{body('HTTP')}
And then I convert the String to JSON to read the desired node with an expression.
json(variables('Content'))?['ExcelFile']
I went a step further and base64 decoded to binary in order to upload to Sharepoint. Going to OneDrive would likely be the same.
base64ToBinary(json(variables('Content'))?['ExcelFile'])

Resources