Azure queue trigger function created with serverless doesn't fire - azure

Creating a queue trigger function using serverless creates the function, but when a new message is added to the queue it doesn't trigger. A queue trigger function created from the portal using the same configuration (queue name, connection string) gets triggered when a new message is added to the queue.
serverless.yml
...
functions:
storageQueue:
handler: src/handlers/goodbye.sayGoodbye
events:
- queue: example-queue
name: myQueueItem
connection: STORAGE_CONNECTION_STRING
This is the json file generated for the queue trigger function from serverless.
function.json
{
"disabled": false,
"bindings": [
{
"type": "queueTrigger",
"direction": "in",
"name": "myQueueItem",
"queueName": "example-queue",
"connection": "STORAGE_CONNECTION_STRING"
}
],
"entryPoint": "sayGoodbye",
"scriptFile": "../src/handlers/goodbye.js"
}
This is the json file generated for the function if its created from the portal. function.json
{
"bindings": [
{
"name": "myQueueItem",
"queueName": "example-queue",
"connection": "STORAGE_CONNECTION_STRING",
"direction": "in",
"type": "queueTrigger"
}
]
}
As you can see the bindings part is the same for both functions, but only the one created from the portal works.

Here is the workaround I did to create an Azure Serverless Function of JavaScript Stack - Azure Queue Storage Trigger in Visual Studio Code and it is triggering successfully after adding a message to the created Queue.
And the code is:
function.json
{
"bindings": [
{
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in",
"queueName": "js-queue-items",
"connection": "storageaccountjbd99_STORAGE"
}
]
}
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
}
}
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "Azure Connection Storage string",
"FUNCTIONS_WORKER_RUNTIME": "node",
"storageaccountjbd99_STORAGE": "Azure Connection Storage string"
}
}
Here the AzureWebJobsStorage and storageaccountjbd99_STORAGE connection string values should be same if you're connecting to Azure Storage Account.
If the storage account is created in Azure, while creating the function it asks to select the Azure Storage account or use local storage account, here I selected the existing Azure Storage account so the connection value is the storage account name.
After that, I run the function and in Azure Storage Explorer, create the queue name called js-queue-items and added the message in the Queue.
After adding the message, the function triggered its functionality and shown the output as you see in below:

Related

Azure functions event hub trigger binding registration failing when deploying code from storage account

Event hub trigger binding registration failing when deploying the code from zipped code in a storage account using the app setting, WEBSITE_RUN_FROM_PACKAGE. Giving the following error:
The binding type(s) eventHubTrigger are not registered
The same code works fine when unzipped deployed through VS code.
Host.json
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
}
Function.json
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"eventHubName": "eventHubName",
"connection": "myEventHubReadConnectionAppSetting"
}
]
}
Update the host.json and Add "extensions"
{
"version": "2.0",
"extensions": {
"blobs": {},
"cosmosDb": {},
"durableTask": {},
"eventHubs": {},
"http": {},
"queues": {},
"sendGrid": {},
"serviceBus": {}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[2.*, 3.0.0)"
}}
Used the above tip of mentioning the extension explicitly in the host.json
Moved the host.json to the one level above the code folder, I was keeping that at the same level.
PS: This was working with VS code deployments using Azure function extension - as when the host.json is not detected on the root level, VS code auto installs the extension based on the trigger specified in functions.json

How can i query data from my azure cosmos db?

I have azure functions written in nodejs. I can't find a way how to get data for example from my created azure cosmos db. I know that there is azure cosmos SDK, but i don't want to use that way.I want to learn to do it through the azure functions because it is possible with them also.
i try do to this:
function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "cosmosDB",
"name": "inputDocument",
"databaseName": "dbtodos",
"collectionName": "items",
"connectionStringSetting": "todos_DOCUMENTDB",
"partitionKey": "/all",
"direction": "in"
}
],
"disabled": false
}
index
module.exports = async function (context, req) {
context.res = {
// status: 200, /* Defaults to 200 */
body: context.bindings.inputDocument
};
};
after my deploy when i visit the automatically generated url - i can't even open the link.There is not requests coming back.
If i do some basic example where i don't try to pull data from the db then my url is working after deploy.
How can i get the data ?
My data in the local.settings.json was wrong. I had azure storage for other table not for the one that i wanted to query... The code works perfectly fine

How to specify a VS Code binding to upload a file from /tmp to blob storage in an Azure Function

I have an Azure Function written in Python 3.8 that creates a text file in /tmp. I want to upload it to blob storage. I am forced to develop locally in VS Code and need a binding in function.json. The problem is that the binding wants me to specify a data item that represents the blob, and since I am creating the blob from scratch by uploading a text file to the Container in the Storage account, I do not have any such data item in my code. So I always error.
Specifically, I have a container named "swsw-2020" in my storage account. Here is the code I am using to upload the file from /tmp to that container.
try:
from azure.storage.blob import BlobServiceClient, BlobClient # noqa
# Create the BlobServiceClient that is used to call the Blob service for the storage account
blob_service_client = BlobServiceClient.from_connection_string(conn_str=connection_string)
# Upload the output file, use destination for the blob name
blob_client = blob_service_client.get_blob_client(
container=container_name, blob=destination)
with open(filename, "rb") as data:
blob_client.upload_blob(data)
except Exception as err:
log_error(f"Failed to upload '{filename}' to Azure Blob Storage: {err}")
And here is my function.json snippet, which is obviously wrong but I have absolutely no idea how to make it right.
{
"type": "blob",
"direction": "out",
"name": "data",
"path": "swsw-2020",
"connection": "AzureWebJobsStorage"
}
I am completely open to better ways to do this. I just want to get my TXT file in /tmp uploaded to a blob in the "swsw-2020" container in my Storage account. Thanks!
Update:
You can use a simply way to dynamic set the blob name:
This is the function.json:
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"route": "{test}",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"name": "outputblob",
"type": "blob",
"path": "test1/{test}.txt",
"connection": "str",
"direction": "out"
}
]
}
Then, for example, if you want to create a blob named 1.txt, you can hit the function like this: http://localhost:7071/api/1
Original Answer:
You can upload the file before stored in some folder.(This is because maybe you will face some problem about access permission.)
It seems you are not using output binding, just connect to storage manully.
The output binding should be used like this:
_init_.py
import logging
import azure.functions as func
def main(req: func.HttpRequest,outputblob: func.Out[func.InputStream],) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
testdata = 'this is test.'
outputblob.set(testdata)
name = req.params.get('name')
return func.HttpResponse(f"This is output binding test, "+name)
function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"name": "outputblob",
"type": "blob",
"path": "test1/test.txt",
"connection": "str",
"direction": "out"
}
]
}
Let me know if have more doubts.

Azure Function binding error for signalR (negotiate function) (500 error code)

I'm creating a live chat using Azure functions and signalR. It works perfectly fine locally, but the deployed "negotiate" function does not work.
negotiate function (index.js)
module.exports = function (context, req, connectionInfo) {
context.res = { body: connectionInfo };
context.done();
}
config file (function.json)
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"direction": "in",
"connectionStringSetting": "AzureSignalRConnectionString"
}
]
}
AzureSignalRConnectionString is set in function app properties.
I also tried using "connectionString" instead of "connectionStringSetting" and using the connection string instead of "AzureSignalRConnectionString" reference, and all 4 possible combinations we have here.
If I run the function in Azure portal, I get this error:
[Error] Executed 'Functions.negotiate' (Failed, Id=0ac24b1f-1ab0-40f5-9680-34db547e1cc9)
Unable to resolve the value for property 'SignalRConnectionInfoAttribute.ConnectionStringSetting'. Make sure the setting exists and has a valid value
Did you write "connectionStringSetting" as the attribute name in your code ? If so, could you please have a try to change it to "ConnectionStringSetting". You may refer to this tutorial or the screenshot I post below:
Solved (got an answer on https://social.msdn.microsoft.com/).
I should have added the AzureSignalRConnectionString in FunctionApp/Configuration/Application settings instead of FunctionApp/Configuration/Application settings/Connection strings.

When I am running azure HTTP Trigger function i am getting 401 unauthorized

I am trying to run Azure HTTP Trigger Azure Function and I am receiving a 401 Unauthorized. It was working fine for me earlier.
When I created the new function under the same Function App and copied the same code then also it is running fine but when I am trying to run my created function then I am getting the same error that I mentioned.
I'm seeing the following logs in the streaming service.
2018-07-02T07:09:41 Welcome, you are now connected to log-streaming service.
2018-07-02T07:09:48.893 [Info] Executing HTTP request: {
"requestId": "53e54698-c46b-4cb6-9ed0-d042eaf9ec71",
"method": "POST",
"uri": "/api/Source/MPAA/false"
}
2018-07-02T07:09:48.893 [Info] Executed HTTP request: {
"requestId": "53e54698-c46b-4cb6-9ed0-d042eaf9ec71",
"method": "POST",
"uri": "/api/Source/MPAA/false",
"authorizationLevel": "Anonymous",
"status": "Unauthorized"
}
This is how I solved the problem based on the cause correctly provided by Nick above. Do this if you don't want to have to open the Azure Function's GUI every time you push your code.
In the source code of the function:
[FunctionName("YourFunctionName")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log){
What I had to do was to change the default setting AuthorizationLevel.Function into AuthorizationLevel.Anonymous. The former only allows triggering from other Function apps, the later will let you trigger from the browser.
If you are managing your code via the azure portal, then simply navigate to "Integrate" and change the "Authorization Level" drop-down to "Anonymous".
If you are managing your code with source control integration (e.g. via git), add this to your function.json:
"authLevel": "anonymous"
Full snippet of function.json:
{
"bindings": [
{
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [ "post" ],
"route": "Source/MPAA",
"authLevel": "anonymous"
},
{
"type": "http",
"name": "res",
"direction": "out"
}
],
"disabled": false
}
Note: the above is just an example, you may have to tweak the route.
Note: the /api is the default prefix, and can be modified in the host.json file.
Its about the authlevel of the function.
If you use the authlevel = anonymous in you function.json file. Then you don't have to pass any access key and you can access the azure function api like the normal api endpoints.
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For example you http trigger is http://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME> you can easily access this without any access/auth key.
If your are using the authlevel = function then you have to pass the access key/Api key with the http trigger endpoint while hitting it. If you don't you will get the 401 unauthorized.
{
"disabled": false,
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
You need to pass the key like as below example.
**https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>
**
For the authlevel = function you can access the http trigger by the function key
and the host key. You will find the Get Function Url section when you open the function in the azure portal.
Note
With the host key you can access all of your http trigger endpoints its going to be common for all the http trigger. But the function key is unique for every function.
The third option is to use the authlevel = admin.
{
"disabled": false,
"bindings": [
{
"authLevel": "admin",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
For auth level admin the http trigger can only be access by the master key.
**https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<MASTER_KEY>
**
You will find all these keys as per the auth levels in the Get Function Url section.
The complete guide for the authlevel is in this link.
Azure Functions HTTP trigger function authlevel Explanation
I hope this will be helpfull.
I started getting 401's too until I realised that I had two functions with the same route. That obviously confused Azure big time.
Check if you don't have different functions with same routes.
I started seeing this response after changing the function runtime version via Azure Portal. Redeploying the function app from Visual Studio resolved the issue for me.

Resources