Anyone know what I am missing here?
I want my proxy to route all requests to my azure function root URL, to my function.
So that this link https://myfunction.azurewebsites.net/
works the same as this link https://myfunction.azurewebsites.net/MYShinyNewFunction
Here is my proxy.json
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Redirector Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET"
]
},
"backendUri": "https://localhost/{*path}"
}
}
}
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"Root URI to Redirector Trigger Function": {
"matchCondition": {
"route": "/{*path}",
"methods": [
"GET"
]
},
"backendUri": "https://myfunction.azurewebsites.net/ActualFunctionName"
}
}
}
Figured it out
Related
How can you create a child resource (e.g. container for Blob Storage, or consumer group for Eventhub) using Logic App?
To create a resource with the ARM connector in Logic App, you need to specify provider and short resource id which are used to construct the path to the new service. However, they do not correspond to the "type" and "name" parameters from ARM template (which would be in the example "Microsoft.Eventhub/namespaces" and "vvtesteventhub").
"inputs": {
"body": {...},
"host": {
"connection": {
"name": "#parameters('$connections')['arm']['connectionId']"
}
},
"method": "put",
"path": "/subscriptions/#{variables('subscriptionId')}/resourcegroups/#{variables('resourceGroup')}/providers/Microsoft.EventHub/namespaces/vvtesteventhub",
"queries": {
"x-ms-api-version": "2021-06-01-preview"
}
}
For a child resource, it is necessary to somehow construct the full path including the parent resource name. However, I am not able to construct it even when editing the directly through the code view (see below). The run fails with error message "Resource not found", despite the fact that it includes the correct path to the existing eventhub where I want to create the consumer group.
{
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['arm']['connectionId']"
}
},
"method": "put",
"path": "/subscriptions/#{variables('subscriptionId')}/resourcegroups/#{variables('resourceGroup')}/providers/Microsoft.EventHub/namespaces/eventhubs/#{variables('eventhubNamespacesName')}/#{variables('eventhubName')}/consumergroups/#{variables('platformName')}",
"queries": {
"x-ms-api-version": "2021-06-01-preview"
}
}
}
We have tested this in our local environment it is working fine, Below statements are based on the analysis.
In our local environment, we have created an event hub Namespace & a logic app.
Using logic app Azure resource Manager connector actions Create or Update a Resource we are able to create EventHub & followed it by a consumer group in it.
Here is the logic app :
Here is the code view of the logic app:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Compose": {
"inputs": "Microsoft.EventHub/namespaces",
"runAfter": {},
"type": "Compose"
},
"Create_a_ConsumerGroup_to_existing_EventHub": {
"inputs": {
"body": {
"location": "westus"
},
"host": {
"connection": {
"name": "#parameters('$connections')['arm']['connectionId']"
}
},
"method": "put",
"path": "/subscriptions/#{encodeURIComponent('<sub-id>')}/resourcegroups/#{encodeURIComponent('<rgName>')}/providers/#{encodeURIComponent(outputs('Compose'))}/#{encodeURIComponent('/<EventHubNamespacesName>/eventhubs/<EventHubName>/consumergroups/<ConsumerGroupName>')}",
"queries": {
"x-ms-api-version": "2021-11-01"
}
},
"runAfter": {
"Creates_a_EventHub_to_existing_EventHubNamespaces_": [
"Succeeded"
]
},
"type": "ApiConnection"
},
"Creates_a_EventHub_to_existing_EventHubNamespaces_": {
"inputs": {
"body": {
"location": "westus"
},
"host": {
"connection": {
"name": "#parameters('$connections')['arm']['connectionId']"
}
},
"method": "put",
"path": "/subscriptions/#{encodeURIComponent('<sub-id>')}/resourcegroups/#{encodeURIComponent('<rgName>')}/providers/#{encodeURIComponent(outputs('Compose'))}/#{encodeURIComponent('/<EventHubNamespacesName>/eventhubs/<EventHubName>')}",
"queries": {
"x-ms-api-version": "2021-11-01"
}
},
"runAfter": {
"Compose": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Hour",
"interval": 3
},
"type": "Recurrence"
}
}
},
"parameters": {
"$connections": {
"value": {
"arm": {
"connectionId": "/subscriptions/<sub-id>/resourceGroups/<rgName>/providers/Microsoft.Web/connections/arm",
"connectionName": "arm",
"id": "/subscriptions/<sub-id>/providers/Microsoft.Web/locations/eastus/managedApis/arm"
}
}
}
}
}
Here is the sample output for reference:
Note:
In order to create a consumer group to EventHub you need to have an existing EventHub or you Need to create a New Event Hub.
I am using the following ARM-template to make a Logic App that posts a message to Slack. However, when it gets deployed I get a Post-message "connection not found" (see image).
What is wrong with the template causing me to get connection not found?
{
"$schema":"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"parameters":{
"slack":{
"defaultValue":"",
"type":"Object"
}
},
"triggers":{
"manual":{
"inputs":{
"schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"properties":{
"context":{
"properties":{
"name":{
"type":"string"
},
"portalLink":{
"type":"string"
},
"resourceName":{
"type":"string"
}
},
"required":[
"name",
"portalLink",
"resourceName"
],
"type":"object"
},
"status":{
"type":"string"
}
},
"required":[
"status",
"context"
],
"type":"object"
}
},
"kind":"Http",
"type":"Request"
}
},
"actions":{
"Post_message":{
"runAfter":{
},
"type":"ApiConnection",
"inputs":{
"host":{
"connection":{
"name":"Hard-coded name here"
}
},
"method":"post",
"path":"/chat.postMessage",
"queries":{
"channel":"slack-channel-name",
"text":"This is a test :) "
}
}
}
},
"outputs":{
}
}
I am adding the parameters with a Python workflow-package in a separate script, imported from:
azure.mgmt.logic.models import Workflow
This seems to be working ok as the Logic App gets deployed just fine, it is only the connection that is missing.
This is occurring, because you have not created a Slack connector and added it's details in the Logic App. The Logic App ARM for this shall look something like:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Post_message": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['slack']['connectionId']"
}
},
"method": "post",
"path": "/chat.postMessage",
"queries": {
"channel": "C0N******UT",
"text": "Hello there!"
}
},
"runAfter": {},
"type": "ApiConnection"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"manual": {
"inputs": {
"schema": {}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
"value": {
"slack": {
"connectionId": "/subscriptions/b8*******23f/resourceGroups/RG_NAME/providers/Microsoft.Web/connections/slack",
"connectionName": "slack",
"id": "/subscriptions/b83c1ed************4c23f/providers/Microsoft.Web/locations/westus2/managedApis/slack"
}
}
}
}
}
The slack connector should be added here:
We are building nested logic apps where a logic app will call another logic app to aggregate some data.
Currently we have Logic Apps A, B and C all being setup with a GET request.
Logic App ABC that aggreagtes all the data will be exposed by the API over a GET request and internally call A to C to gather all the data.
When we use Postman however we get an error message:
{
"error": {
"code": "TriggerRequestMethodNotValid",
"message": "The HTTP method for this request is not valid: expected 'Get' and actual 'POST'."
}
}
Which would imply that ABC calls A with a POST instead of a GET.
We've got the hunch, that this is due to us calling the Logic App with a body element.
We temporarly fixed the problem by setting all logic app calls to POST, but we would like to avoid this, since we might expose A as system layer API and would like to keep it as a GET.
The code for A:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Filter_is_null": {
"actions": {
"Get_locations": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['salesforce']['connectionId']"
}
},
"method": "get",
"path": "/datasets/default/tables/#{encodeURIComponent(encodeURIComponent('Location__c'))}/items"
},
"runAfter": {},
"type": "ApiConnection"
},
"Response": {
"inputs": {
"body": "#body('Get_locations')?['value']",
"statusCode": 200
},
"kind": "Http",
"runAfter": {
"Get_locations": [
"Succeeded"
]
},
"type": "Response"
}
},
"else": {
"actions": {
"Get_locations_filtered": {
"inputs": {
"host": {
"connection": {
"name": "#parameters('$connections')['salesforce']['connectionId']"
}
},
"method": "get",
"path": "/datasets/default/tables/#{encodeURIComponent(encodeURIComponent('Location__c'))}/items",
"queries": {
"$filter": "#triggerBody()?['filter']"
}
},
"runAfter": {},
"type": "ApiConnection"
},
"Response_error": {
"inputs": {
"body": {
"component": "sf-locations-get",
"message": "bad request - validate filter"
},
"statusCode": 400
},
"kind": "Http",
"runAfter": {
"Get_locations_filtered": [
"Failed"
]
},
"type": "Response"
},
"Response_filtered": {
"inputs": {
"body": "#body('Get_locations_filtered')?['value']",
"statusCode": 200
},
"runAfter": {
"Get_locations_filtered": [
"Succeeded"
]
},
"type": "Response"
}
}
},
"expression": {
"and": [
{
"equals": [
"#triggerBody()?['filter']",
"#null"
]
}
]
},
"runAfter": {},
"type": "If"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"request": {
"inputs": {
"method": "GET",
"schema": {
"properties": {
"filter": {
"type": "string"
}
},
"type": "object"
}
},
"kind": "Http",
"type": "Request"
}
}
},
"parameters": {
"$connections": {
}
}
}
Image of A for reference:
Image of ABC for reference:
Is there a possibility to call nested logic apps, containing a body using GET?
You can call another logic app from one logic app and pass a body to it.
If you are calling another logic app which triggers with a http request the method expected is generally POST. Try to pass the body and check if that helps in your case.
Please refer to this document
You may also check these and see if these suffices your requirement:
https://www.serverlessnotes.com/docs/nested-logic-apps
https://blog.sandro-pereira.com/2016/04/19/the-ability-to-call-nested-logic-apps-directly-from-logic-apps-designer/
Using a body in a GET request breaks the internet.
In short, this breaks the semantics that a resource-uri in combination with the headers is the cacheable key. When you add a body to the GET request, the caching ability is removed.
It is by design that you cannot and should not add a body to a GET request.
You should rethink your call setup and when you need to send a body, then you need to use other HTTP methods that do not break proper semantics. e.g. POST, PUT, etc.
More info: https://stackoverflow.com/a/983458/1581925
I am trying to add a custom HTTP header to all of my responses of my Azure Functions - lets call it X-Custom. Then I add a proxies.json file like this to my functions project:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"add-custom-header-to-response": {
"matchCondition": {
"route": "/{*restOfPath}"
},
"responseOverrides": {
"response.headers.X-Custom": "Custom value"
}
}
}
}
And this works as expected, I do get the X-Custom header, but my response content has gone missing. What am I missing in the proxies.json file?
Update
Thanks to Baskar I came to the solution (I was missing backendUri):
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"add-custom-header-to-response": {
"matchCondition": {
"route": "/api/1/{*restOfPath}"
},
"backendUri": "https://localhost/api/1/{restOfPath}",
"responseOverrides": {
"response.headers.X-Custom": "Custom value"
}
}
}
}
Also see:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-proxies#reference-localhost
https://learn.microsoft.com/en-us/azure/azure-functions/functions-proxies#route-template-parameters
Just tested my azure function with the route as "test" and I have overriden my response status code and status description and added custom header. Your proxies.json is missing a function backend url.
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"test": {
"matchCondition": {
"route": "test"
},
"backendUri": "https://testbasenewtest.azurewebsites.net/api/HttpTrigger1",
"responseOverrides": {
"response.statusCode": "200",
"response.statusReason": "Successful Response",
"response.headers.API_Login": "custom"
}
}
}
}
I want to create Azure Logic App which will constantly request a specific website on the Internet and parse received HTML.
I've created Logic App and set up interval and HTTP request action.
Which action should I choose as the next step for simple regex operation on HTML code?
What comes to my mind is creating Azure Function which will do the job, but I wonder if there is any other solution, more suitable for such task.
I want it the be simple as possible.
Edit:
Just found out some cool feature. Logic Apps contain some basic expressions for primitive types.
Unfortunetly it lacks of any regex or string.contains.
For now, I'll try with Azure Functions.
I've managed to solve my problem with use of Workflow Definition Language and building blocks provided by Azure.
The Azure Function idea was not that bad and would fit perfectly for any more complex case, but as I mentioned, I wanted it as simple as possible, so here it is.
This is how my flow looks now.
For sake of completeness, here is the flow in JSON format
{
"$connections": {
"value": {
"wunderlist": {
"connectionId": "/subscriptions/.../providers/Microsoft.Web/connections/wunderlist",
"connectionName": "wunderlist",
"id": "/subscriptions/.../providers/Microsoft.Web/locations/northeurope/managedApis/wunderlist"
}
}
},
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Condition": {
"actions": {
"Create_a_task": {
"inputs": {
"body": {
"completed": false,
"list_id": 000000000,
"starred": true,
"title": "#{variables('today date')}"
},
"host": {
"connection": {
"name": "#parameters('$connections')['wunderlist']['connectionId']"
}
},
"method": "post",
"path": "/tasks",
"retryPolicy": {
"type": "none"
}
},
"limit": {
"timeout": "PT20S"
},
"runAfter": {},
"type": "ApiConnection"
},
"Set_a_reminder": {
"inputs": {
"body": {
"date": "#{addHours(utcNow(), 3)}",
"list_id": 000000,
"task_id": "#body('Create_a_task')?.id"
},
"host": {
"connection": {
"name": "#parameters('$connections')['wunderlist']['connectionId']"
}
},
"method": "post",
"path": "/reminders",
"retryPolicy": {
"type": "none"
}
},
"limit": {
"timeout": "PT20S"
},
"runAfter": {
"Create_a_task": [
"Succeeded"
]
},
"type": "ApiConnection"
}
},
"expression": "#contains(body('HTTP'), variables('today date'))",
"runAfter": {
"Initialize_variable": [
"Succeeded"
]
},
"type": "If"
},
"HTTP": {
"inputs": {
"method": "GET",
"uri": "..."
},
"runAfter": {},
"type": "Http"
},
"Initialize_variable": {
"inputs": {
"variables": [
{
"name": "today date",
"type": "String",
"value": "#{utcNow('yyyy/MM/dd')}"
}
]
},
"runAfter": {
"HTTP": [
"Succeeded"
]
},
"type": "InitializeVariable"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"parameters": {
"$connections": {
"defaultValue": {},
"type": "Object"
}
},
"triggers": {
"Recurrence": {
"recurrence": {
"frequency": "Day",
"interval": 1,
"startTime": "2017-08-01T23:55:00Z",
"timeZone": "UTC"
},
"type": "Recurrence"
}
}
}
}
You can use inline code action in logic app to run javascript regex code (preview- May 2019) (Not supported on Flow).
Iniline Code
Logic App Inline Code Ref
You're probably on the right track. An Azure Function would be the most appropriate way to implement this right now. An API App is an option but that's a heavier platform than you need.
create an Azure Function along the lines of:
{
log.Info("C# HTTP trigger function processed a request.");
// Get request body
dynamic data = await req.Content.ReadAsAsync<object>();
// Set name to query string or body data
string input = data?.input.ToString();
var regexJson = data?.regexList;
var regexes = regexJson.ToObject<List<RegexReplace>>();
foreach (var regex in regexes)
{
var re = Regex.Replace(regex.Regex, "\\\\","\\");
var replace = Regex.Replace(regex.Replace, "\\\\","\\");
input = Regex.Replace(input, "\\\"","\"");
input = Regex.Replace(input, re, replace);
}
input = Regex.Replace(input, "[\\r\\n]", "");
return data.regexList == null
? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
: req.CreateResponse(HttpStatusCode.OK, input, "application/json");
}
public class RegexReplace
{
public string Regex { get; set; }
public string Replace { get; set; }
}
This is my function to use for replacing text in a string. this is reusable and the approach can be used for many similar type of aspects of working in Logic Apps:
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
dynamic data = await req.Content.ReadAsAsync<object>();
string removeme = data?.removeme;
string replacewith = data?.replacewith;
string value = data?.value;
return req.CreateResponse(HttpStatusCode.OK, value.Replace(removeme, replacewith));
}
I would then post an object like this from my logic app:
{
"removeme": "SKU-",
"replacewith": "P-",
"value": "SKU-37378633"
}
... to get the result: "P-37378633"