Error while trying to bind Azure Function to CosmosDB - azure

I want to connect my Azure Function with my CosmosDB collection using DocumentDB output binding.
My Function:
public static class HttpTriggerSave
{
[FunctionName("HttpTriggerSave")]
public static void Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, [DocumentDB("dbName", "collectionName", Id = "id")] dynamic outputDoc, TraceWriter log)
{
outputDoc = new
{
Text = "text",
id = Guid.NewGuid()
};
}
}
My local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"AzureWebJobsDashboard": "",
"AzureWebJobsServiceBus": "Endpoint=sb://<namespace>/;SharedAccessKeyName=<keyname>;SharedAccessKey=<key>",
"AzureWebJobsDocumentDBConnectionString": "mongodb://..."
}
}
However I get every time the same error:
mscorlib: Exception while executing function: HttpTriggerSave. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'outputDoc'. Microsoft.Azure.Documents.Client: Value cannot be null.
Parameter name: authKeyOrResourceToken.
How can I fix that?

mscorlib: Exception while executing function: HttpTriggerSave. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'outputDoc'. Microsoft.Azure.Documents.Client: Value cannot be null.
Parameter name: authKeyOrResourceToken.
According to the exception, it indicates that it has no access to Documentdb. According to your local.settings.json that you use the MongoDb connection string.
So please use the documentdb connection string.
AccountEndpoint=https://{documentDbName}.documents.azure.com:443/;AccountKey=xxxxx;
And I also do a demo on my side, it works correctly.
[FunctionName("HttpTriggerSave")]
public static void Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req,[DocumentDB("tomdb", "collectionId")] out dynamic outputDoc, TraceWriter log)
{
outputDoc = new
{
Text = "text",
Id= Guid.NewGuid()
};
}

Related

Azure Durable Functions - OrchestrationTrigger stuck

I am new to azure durable functions. I have created a sample azure durable function using vs 2019. I am running default generated azure durable function template code locally with azure storage enumerator and when I run the durable function, the OrchestrationTrigger stuck and not able to resume.
The hub name is samplehubname. There a pending records present in the samplehubnameInstances azure table but there is no records in the samplehubnameHistory azure table.
There is no exception and no errors in the code.
SampleFunction.cs
public static class SampleFunction
{
[FunctionName("SampleFunction")]
public static async Task<List<string>> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var outputs = new List<string>();
// Replace "hello" with the name of your Durable Activity Function.
outputs.Add(await context.CallActivityAsync<string>("SampleFunction_Hello", "Tokyo"));
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return outputs;
}
[FunctionName("SampleFunction_Hello")]
public static string SayHello([ActivityTrigger] string name, ILogger log)
{
log.LogInformation($"Saying hello to {name}.");
return $"Hello {name}!";
}
[FunctionName("SampleFunction_HttpStart")]
public static async Task<HttpResponseMessage> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestMessage req,
[DurableClient] IDurableOrchestrationClient starter,
ILogger log)
{
// Function input comes from the request content.
string instanceId = await starter.StartNewAsync("SampleFunction", null);
log.LogInformation($"Started orchestration with ID = '{instanceId}'.");
return starter.CreateCheckStatusResponse(req, instanceId);
}
}
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureWebJobsSecretStorageType": "files", //files
"MyTaskHub": "samplehubname"
}
}
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensions": {
"durableTask": {
"hubName": "%MyTaskHub%"
}
}
}
samplehubname-control-03 Message Queue
{"$type":"DurableTask.AzureStorage.MessageData","ActivityId":"72b75a34-e403-4772-aed0-fbb10039795a","TaskMessage":{"$type":"DurableTask.Core.TaskMessage","Event":{"$type":"DurableTask.Core.History.ExecutionStartedEvent","OrchestrationInstance":{"$type":"DurableTask.Core.OrchestrationInstance","InstanceId":"f8d0499a4297480c8bdf4a56954861d3","ExecutionId":"2e46b87e4cf74c2dab572d92e012bded"},"EventType":0,"ParentInstance":null,"Name":"Function1","Version":"","Input":"null","Tags":null,"EventId":-1,"IsPlayed":false,"Timestamp":"2021-09-21T15:41:35.0156514Z"},"SequenceNumber":0,"OrchestrationInstance":{"$type":"DurableTask.Core.OrchestrationInstance","InstanceId":"f8d0499a4297480c8bdf4a56954861d3","ExecutionId":"2e46b87e4cf74c2dab572d92e012bded"}},"CompressedBlobName":null,"SequenceNumber":1,"Sender":{"$type":"DurableTask.Core.OrchestrationInstance","InstanceId":"","ExecutionId":""}}
Any help will appreciated.
If your orchestration code has contain a loop too much, the guidance in our Eternal orchestration documentation.
In your code there is not much loop available. So, you need to use the durable functions eternal orchestrations TerminateAsync (.NET) method of the orchestration client binding to stop it.
Add your durable function into application insights to check the clear view of issue. It may help to fix the issue.
Check the similar issue here.
Try the steps and use fan in/ fan out in durable function durable functions patterns fan out and fan in

How can I inject the default azure function logger in other classes?

I´m using azure functions using dotnet core 3.1 and I cannot make my custom logs work as expected.
In my values section of the local.settings.json file i put the following key: APPINSIGHTS_INSTRUMENTATIONKEY and i read on the docs that the functions runtime add the log automatically.
I can see the default logs on the application insights panel, but my custom logs are not being write there. On my class I did this:
private readonly ILogger<LoginService> _logger;
public CustomService(ILogger<CustomService> logger)
{
_logger = logger;
}
public void Test()
{
_logger.LogError("TestLog");
}
How is the proper way of injecting the default logging in the constructor of other classes which is not the function method itself?
ILogger is indeed not a valid injections. ILogger does work and
creates a filter of type T. However you need to manually add the
ability to listen to custom filters (in this case your class) for them
to show up. you can do that in host.json. Here's a sample.
host.json:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingExcludedTypes": "Request",
"samplingSettings": {
"isEnabled": true
}
},
"logLevel": {
"Hollan.Functions.HttpTrigger": "Information"
}
}
}
HttpTrigger.cs
public class HttpTrigger
{
private readonly ILogger<HttpTrigger> _log;
public HttpTrigger(ILogger<HttpTrigger> log)
{
_log = log;
}
[FunctionName("HttpTrigger")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
{
_log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
}
Source: https://github.com/Azure/Azure-Functions/issues/1484

FromQuery support in Azure Functions v3

I am trying to use [FromQuery] with Azure Function v3 but I am getting the following error:
Cannot bind parameter 'search' to type String.
For the following method:
[FunctionName("GetObjects")]
public ActionResult<IActionResult> QueryObjects(
[HttpTrigger(AuthorizationLevel.Function, "GET", Route = "objects")]
HttpRequest req,
ILogger log,
[FromQuery] string search = null)
{
//do some stuff
}
Is [FromQuery] not supported?
Should I use req.Query["search"] to get the query parameter?
From functions.desp.json
Related to binding
"Microsoft.Extensions.Configuration.Binder/3.1.1": {
"dependencies": {
"Microsoft.Extensions.Configuration": "3.1.2"
},
"runtime": {
"lib/netcoreapp3.1/Microsoft.Extensions.Configuration.Binder.dll": {
"assemblyVersion": "3.1.1.0",
"fileVersion": "3.100.119.61404"
}
}
},
This is what you face now:
Method signatures developed by the azure function C # class library can include these:
ILogger or TraceWriter for logging (v1 version only)
A CancellationToken parameter for graceful shutdown
Mark input and output bindings by using attribute decoration
Binding expressions parameters to get trigger metadata
From this doc, it seems that it is not supported. You can create your custom binding like this, and dont forget to register it in the startup.
If you want to bind it directly, it's not possible. So you could try to change your route like Function1/name={name}&research={research} then bind it to string parameter.
Below is my test code:
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route="Function1/name={name}&research={research}")] HttpRequest req,
String name,
String research,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
log.LogInformation(research);
string responseMessage = $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}

Why Azure function is not writing to Service Bus Topic

My function is like
[FunctionName("MyFunctionName")]
[return: ServiceBus("mytopic", Connection = "ServiceBusConnectionString")]
public static async Task<string> MyFunctionAsync([QueueTrigger("my-input-queue")] string msgIn, TraceWriter log)
{
My local.settings.json has
{
"IsEncrypted": false,
"Values": {
"ServiceBusConnectionString": "[my connection string]"
}
}
where [my connection string] is copy-pasted from a Primary Connecting String under one of the Shared access policies with a Send claim.
This just silently fails: Messages get stuck in my-input-queue and no errors are written to log streaming. However I'm 100% sure the attribute is the issue because I've deployed 100 different combinations of this to try and make it work :).
Any ideas?
Based on my test,it should work with servicebus attribute. The following is my test code.
[return: ServiceBus("topicName",Connection = "ServiceBusConnectionString", EntityType = EntityType.Topic)]
public static async Task<string>Run([QueueTrigger("queueName")]string myQueueItem, TraceWriter log)
{
...
return myQueueItem; // write to the Topic.
}
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "xxxxxx",
"AzureWebJobsDashboard": "xxxxxxxx",
"ServiceBusConnectionString": "xxxxxx"
}
}
You could get more information about Azure Service Bus output binding from this tutorial. You also could do that with follwoing way
[FunctionName("ServiceBusOutput")]
public static void Run([[QueueTrigger("queueName")]string myQueueItem,
TraceWriter log,
[ServiceBus("topicName",Connection = "ServiceBusConnectionString", EntityType = EntityType.Topic)]out string queueMessage)
{
log.Info("Azure Function Demo - Azure Service Bus Queue Topic");
queueMessage = myQueueItem;
}
You are missing the required settings for your QueueTrigger, so your function isn't triggering on new items in the queue. You should have values for AzureWebJobsStorage and AzureWebJobsDashboard, and your QueueTrigger should have a value for the Connection field.
For more information about how to wire up QueueTriggers and test locally, see this answer.

Is Attribute Routing possible in Azure Functions

I am trying to enforce a route parameter to be guid but getting below error
"Exception while executing function: GetUser -> One or more errors
occurred. -> Exception binding parameter 'req' -> Invalid cast from
'System.String' to 'System.Guid'."
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Admin, "get", Route = "GetUser/{userId:guid}")] HttpRequestMessage req,
Guid userId, ILogger log)
{
}
The request i am making is http://localhost:7071/api/GetUser/246fb962-604d-4699-9443-fa3fa840e9eb/
Am i missing some thing? Cannot we enforce route parameter to be guid ?
Invalid cast from 'System.String' to 'System.Guid'
I can reproduce same issue when use Route constraint {userId:guid} in Azure httptrigger function on my side, you can try to open an issue to give a feedback.
Besides, if possible, you can try to call Guid.TryParse method to convert the string back to Guid value in function code, the following code is for your reference.
public static string Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "GetUser/{userId:guid}")]HttpRequestMessage req, string userId, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
Guid newGuid;
var resmes = "";
if (Guid.TryParse(userId, out newGuid))
{
resmes = "userid: " + newGuid;
}
else {
resmes = "error";
}
return resmes;
}

Resources