Error with Azure Function Service Bus Output Binding - azure

I'm having an issue with an Azure Service Bus output binding that I'm uncertain about how to proceed with. I've had no luck finding a similar question, so I apologize if this is a duplicate.
I'm trying to use the local VS 2017 development process, so the function.json bindings should be generated automatically. The function signature is as follows:
[FunctionName("RequestNewPaladinInvitation")]
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post")]HttpRequestMessage req,
[ServiceBus("thequeue")] ICollector<Invitation> invitationOutputQueue,
TraceWriter log)
{
//Do some stuff and write to the queue
invitationOutputQueue.Add(invite);
}
I get the following error when running the function locally.
Microsoft.Azure.WebJobs.Host: Error indexing method
'RequestNewPaladinInvitation.Run'. Microsoft.Azure.WebJobs.Host:
Cannot bind parameter 'invitationOutputQueue' to type ICollector`1.
Make sure the parameter Type is supported by the binding. If you're
using binding extensions (e.g. ServiceBus, Timers, etc.) make sure
you've called the registration method for the extension(s) in your
startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).
[9/1/2017 5:42:49 PM] Error indexing method
'RequestNewPaladinInvitation.Run'
Both my host.json and local.settings.json are defined as follows:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "<MyStorageAccountInfo>",
"AzureWebJobsDashboard": "<MyDashboardInfo>",
"AzureWebJobsServiceBus": "<MyServiceBusConnectionString>"
}
}
I was under the impressing that defining the AzureWebJobsServiceBus value would make that the default ServiceBusAccount for any ServiceBus bindings throughout the function app.
I also tried explicitly pointing the ServiceBus binding to the connection string for the account with the following alternative attribute [ServiceBus("createpaladininvitation",Connection = "ServiceBus")]. My understanding of the convention is that the AzureWebJobs portion of the property should not be included. Just in case I misunderstood, I tried [ServiceBus("createpaladininvitation",Connection = "AzureWebJobsServiceBus")] as well. I even tried to decorate both the method and parameter with the following attribute, [ServiceBusAccount("ServiceBus")]. I also tried the same variations as with the Connection parameter for the ServiceBus attribute.
In all cases, I get the same function.json output, which shows no binding generated for the ServiceBus output binding.
Here's the function.json:
{
"generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
"configurationSource": "attributes",
"bindings": [
{
"type": "httpTrigger",
"methods": [
"post"
],
"authLevel": "anonymous",
"name": "req"
}
],
"disabled": false,
"scriptFile": "..\\bin\\AzureFunctionsPoc.dll",
"entryPoint": "AzureFunctionsPoc.RequestNewPaladinInvitation.Run"
}
It feels like I'm missing something obvious.
[Update]
As I tried to continue to figure out what's going on, I ran the function locally and edited the generated function.json file and added the binding that I think should have been generated. The resulting manually edited function.json is:
{
"generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
"configurationSource": "attributes",
"bindings": [
{
"type": "httpTrigger",
"methods": [
"post"
],
"authLevel": "anonymous",
"name": "req"
},
{
"type": "serviceBus",
"name": "invitationOutputQueue",
"queueName": "createpaladininvitation",
"connection": "ServiceBus",
"direction": "out"
}
],
"disabled": false,
"scriptFile": "..\\bin\\AzureFunctionsPoc.dll",
"entryPoint": "AzureFunctionsPoc.RequestNewPaladinInvitation.Run"
}
With those edits, the method works exactly as expected.
This feels even more like either a syntax or convention issue that I'm missing, or a tooling bug.

There is currently an outstanding tooling bug in regards to ServiceBus output triggers. It will work if you 'deploy' your app to Azure Functions, just not locally with the tooling
Please see relevant GitHub issues here: Service Bus output binding issue
and here: Latest v1.0.0 not working with ServiceBus. alpha 6 still works.
This is related to the lazy load. We're not picking up the service bus extension, hence the indexing error. (Azure/azure-webjobs-sdk-script#1637)
The reason for that is that ServiceBus extension is different than the others. We expect extensions to have a public parameterless config object that implements IExtensionConfigProvider.
SB is internal (https://github.com/Azure/azure-webjobs-sdk/blob/663a508e8a851629c26a51e7de3af36629dfd120/src/Microsoft.Azure.WebJobs.ServiceBus/Config/ServiceBusExtensionConfig.cs#L17 ) so our scan for ExportedTypes misses it (see https://github.com/Azure/azure-webjobs-sdk-script/blob/b1445485807bb190ba0716af1a8dc81a864b5228/src/WebJobs.Script/Host/ScriptHost.cs#L735) .
SB's config does not have a parameterless ctor, so the Activator.createInstance call will fail too.
This hotfix (which we made to script runtime) Azure/azure-webjobs-sdk-script#1804 would fix it; but that would need to be pulled to CLI.

Related

Issue on Azure Function during the configuration of CosmosDB output binding with Managed System identity

Currently on one of my project, I've an Azure function (NodeJS 16) running to be triggered on a blob creation and that need to take few informations and saved them to a cosmos db. For that I use a Cosmos DB output binding.
At the start, I used the classic connection for that with the connection string. It worked well. But now, I don't want to deal with the rotation of the keys for this connection string. That's why I wanted to move to the version 4+ of the azure extension in order to connect with Managed System Identity.
Right now it works well for the blob trigger with MSI, it is triggered and it run the function. But at the end, when I do the context.done() in order to save the datas to the cosmos db, I get this error.
2022-10-31T15:59:00.203 \[Error\] Executed 'Functions.SaveToCosmosDB' (Failed, Id=9162f53b-8c79-44bf-82b9-ca9c4267cc76, Duration=359ms)
Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified
I'm stuck with it since fews days. I don't get it, why do I get a .NET package error ? I'm using a NodeJS function. Do someone already get this issue before ? Or am I wrong with my configuration ?
Thanks in advance for your help
Here is my host.json:
{
"version": "2.0",
"extensionBundle":
{
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
"version": "[4.*, 5.0.0)"
}
}
and here is my function.json
{
"bindings": [
{
"name": "imageBlob",
"type": "blobTrigger",
"direction": "in",
"path": "images/{name}.bmp",
"connection": "MYAPP_BLOB"
},
{
"direction": "out",
"name": "metadata",
"type": "cosmosDB",
"databaseName": "MYAPP_COSMOS_DATABASE",
"containerName": "MYAPP_COSMOS_CONTAINER",
"connection": "MYAPP_COSMOS",
"preferredLocations": "Central US"
}
]
}
When I change from extension version 3+ to 4+, I change the property collectionName to containerName as described in the MS documentation https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-cosmosdb-v2-output?tabs=in-process%2Cextensionv4&pivots=programming-language-javascript
But I've seen a mismatch in the documentation, for the .Net version, if we use a 4+ version of the extension, the property ConnectionStringSetting change for Connection but for the JS version of the code, it remains ConnectionStringSetting. Is it normal or is it a typos mistake in the documentation ?
Thanks in advance for your help.

Default Azure Function app base path D:\home\site\wwwroot Azure Function 2.x

Currently, by default, Azure function base path is set to "D:\home\site\wwwroot". For example, when publishing, VS uploads app to this folder.
I need to read config file from this folder. We have problem of ExecutionContext is null via dependency injection via constructor
Setting a new environment variable might cause issue if the path is changed in the future.
My question is that how can I use app base path that is reliable and stable, that works with DI via constructor.
Azure Function 2.x
VS 2017
you can use function.json to have your configuration key pairs.
for example:
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
and in function.json you can do like this:
"mykey": "myvalue"
{
"generatedBy": "Microsoft.NET.Sdk.Functions-1.0.24",
"configurationSource": "attributes",
"bindings": [
{
"direction":"in",
"type": "timerTrigger",
"useMonitor": true,
"runOnStartup": false,
"name": "myTimer",
"mykey": "myvalue"
}
],
"disabled": false,
"scriptFile": "../bin/**.dll",
"entryPoint": "**.Run"
}
There is an environment variable pointing to home directory. This would not change as many services including function app take dependency on it. Below is how function runtime fetches it in azure environment.
string home = GetEnvironmentVariable("HOME");
Path = System.IO.Path.Combine(home, "site", "wwwroot");

Output binding and generation of function.json

I'm trying to create an Azure function that will output to a table. I'm using the Azure Function App, and so, as I currently understand it, the function.json is generated for me by the SDK. My function definition is as follows:
public static HttpResponseMessage Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req,
TraceWriter log,
[StorageAccount("table_storage")] ICollector<TableItem> outputTable)
I've defined TableItem as a class that inherits from TableEntity. When I deploy this and look at the generated function.json, it doesn't mention the output parameter binding:
{
"generatedBy": "Microsoft.NET.Sdk.Functions.Generator-1.0.7",
"configurationSource": "attributes",
"bindings": [
{
"type": "httpTrigger",
"methods": [
"post"
],
"authLevel": "function",
"name": "req"
}
],
"disabled": false,
"scriptFile": "../bin/FunctionApp5.dll",
"entryPoint": "FunctionApp5.DeliveryComplete.Run"
}
If I run this from Visual Studio, I get the following error:
Cannot bind parameter 'outputTable' to type ICollector`1
I have a few questions about this behaviour: the first and main one is, why is function.json not showing the output binding? Secondly, I understand why this can't be edited when you deploy from VS, but is there a way to manage the bindings without guesswork (I came across using ICollector in this post), but I can't find anywhere else that says it should or shouldn't be there.
Finally, how does (or does) running this from the desktop interact with the published function: does it connect to the published version of the function, or does it generate the function.json locally?
That's a common source of confusion, but input and output bindings are not visible in generated function.json, only trigger does. They will still work normally.
If you are trying to write to Table Storage, you should use Table attribute instead of StorageAccount. ICollector is mentioned in Azure Table storage bindings for Azure Functions.
When running locally, the files stay locally and run in local runtime, without deployment to Azure. They might still interact with real Azure services via bindings.

Debugging Azure function as a C# Web Application

I have a simple trigger based Azure function which connects to an Azure event hub and writes out a message each time one is received on the event hub.
I created this as a C# Web Application based on the below post and am trying to debug this function locally:-
https://blogs.msdn.microsoft.com/appserviceteam/2017/03/16/publishing-a-net-class-library-as-a-function-app/
Here is my function code:-
using Microsoft.Azure.WebJobs.Host;
using System;
using System.Threading.Tasks;
namespace FunctionLibrary
{
public class EventHubProcessorFunction
{
public static void Run(string myEventHubMessage, TraceWriter log)
{
log.Info($"C# Event Hub trigger function processed a Vineet message: {myEventHubMessage}");
}
}
}
Here is my function.json
{
"disabled": false,
"scriptFile": ".\\bin\\FunctionAsWebApp.dll",
"entryPoint": "FunctionLibrary.EventHubProcessorFunction.Run",
"bindings": [
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"path": "edpvineethub",
"connection": "AzureWebJobsServiceBus"
}
]
}
My folder structure is as below:-I have included the following files in the web application project:-
bin\FunctionAsWebApp.dll
NameOfYourFunction\function.json
AnotherFunctionIfYouHaveOne\function.json
appsettings.json
host.json
However I am getting the below error message when trying to run locally;-
No job functions found. Try making your job classes and methods public. If you'r
e using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've call
ed the registration method for the extension(s) in your startup code (e.g. confi
g.UseServiceBus(), config.UseTimers(), etc.).
Any help would be appreciated.
Check that your folder structure looks like this:
bin\FunctionAsWebApp.dll
NameOfYourFunction\function.json
AnotherFunctionIfYouHaveOne\function.json
appsettings.json
host.json
And function.json should of course reference the binary accordingly
"scriptFile": "..\\bin\\FunctionAsWebApp.dll"
Your initialization is likely failing to perform a lookup on the SB connection string, as it expects an App Setting/Environment variable name and you have the actual connection string there.
Please update your function.json to use an App Setting name, defined in your appsettings.json locally and the Function App settings when hosted, with the connection string set as its value.
Important: Since you have your connection string pasted above, I strongly recommend resetting your credentials.

Azure-functions: Can environment variables be used in function.json?

I'm currently using the git push deployment option to deploy a few copies of an azure-function. The function's function.json file has multiple "connection" entries linking to different storage accounts (i.e. for a blob trigger & table output). In different copies of the deployed function I'd like to connect to different storage accounts. Is there any special syntax that can be used in function.json to populate the "connection" string from an environment variable?
I guess an alternative would be to edit function.json as part of a custom kudu step, but environment variables seems more consistent with the other azure app service offerings.
This already works, and is actually the recommended way for you to handle connection strings, since you don't want those checked in with your source code. You can use an app setting name for the connection value, and we'll resolve it. In the following EventHub triggered function, the values MyEventHubReceiver, MyEventHubSender and MyEventHubPath will be auto resolved from app settings:
"bindings": [
{
"type": "eventHubTrigger",
"name": "input",
"direction": "in",
"connection": "MyEventHubReceiver",
"path": "%MyEventHubPath%"
},
{
"type": "eventHub",
"name": "output",
"direction": "out",
"connection": "MyEventHubSender",
"path": "%MyEventHubPath%"
}
]
}
In general, most of the binding properties support the %% resolution syntax, allowing you to store the actual values in app settings for both security as well as configurability.

Resources