I have a http-trigger with a CosmosDB output binding and a simplest of a function as below.
public static class AddRequest
{
[FunctionName("AddRequest")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
ILogger log, [CosmosDB(
databaseName: "haveThatDB",
collectionName: "Requests",
ConnectionStringSetting = "MongoDBEndPoint",CreateIfNotExists =true)] IAsyncCollector<Request> requestOutput
)
{
string jsonContent = await req.ReadAsStringAsync();
dynamic data = JsonConvert.DeserializeObject(jsonContent);
await requestOutput.AddAsync(data);
return req != null
? (ActionResult)new OkObjectResult($"Hello, ras")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
when i executed i get an error
Exception binding parameter 'requestOutput'. System.Private.CoreLib: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters
i am using V2 of azure functions.
i have observed that removing the output binding works. so looks like something is up with this output binding.
local.settings contents are as below
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"MongoDBEndPoint": "AccountEndpoint=https://abc.documents.azure.com:10255;AccountKey=xxxxxxxxxxxxyyyyyyyyzzzzzzz",
"MongoDBName": "haveThatDB"
}
}
any help will be appreciated.
Azure Cosmos DB bindings are only supported for use with the SQL API. For all other Azure Cosmos DB APIs, you should access the database from your function by using the static client for your API, including MongoDB API, Cassandra API, Gremlin API, and Table API.
Supported APIs
Azure Cosmos DB bindings for Azure Functions 2.x
Related
i am currently developing a real time analytic Dashboard with Stream Analytics -> Azure Functions -> SignalRService -> Angular Web App.
I am struggling when i want to authorize my function with the signalr service. Therefore i added the Connectionstring to my Appsettings. When i try to send a SignalRMessage, it says that i am unauthroized. Isnt it just setting the Connectionstring with the Accesskey in AppSettings of the Function?
Current Error:
Microsoft.Azure.SignalR.Common.AzureSignalRUnauthorizedException: 'Authorization failed. If you were using AccessKey, please check connection string and see if the AccessKey is correct. If you were using Azure Active Directory, please note that the role assignments will take up to 30 minutes to take effect if it was added recently. Request Uri: https://signalrtest2.service.signalr.net/api/v1/hubs/pa'
FunctionCode:
[FunctionName("CreateRealTimeAnalytics")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[SignalR(HubName = "pa")] IAsyncCollector<SignalRMessage> signalRMessages)
{
// Extract the body from the request
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
if (string.IsNullOrEmpty(requestBody)) { return new StatusCodeResult(204); } // 204, ASA connectivity check
var data = JsonConvert.DeserializeObject<StreamUsageHeartbeatAnalytics>(requestBody);
var dataString = Newtonsoft.Json.JsonConvert.SerializeObject(data);
await signalRMessages.AddAsync(
new SignalRMessage
{
Target = "pa",
Arguments = new[] { dataString }
});
return new OkResult(); // 200
}
[FunctionName("Negotiate")]
public static SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req,
[SignalRConnectionInfo(HubName = "pa")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
To achieve the above requirement we have tried to add the below connection string format which is working fine So please make sure that you have provided proper Connection string with below format in your Appsettings.
Azure__SignalR__ConnectionString : Value(My connection string)
For more information please refer the below Links:-
MICROSOFT DOCUMENTATION - Azure Function SignalIR Bindings
SO THREAD:- Unable to read Azure SignalR Connection String from Azure App Service Configuration Application Settings
I'm having an azure function that is binded to a service bus, I'm using it like this:
[FunctionName("MyFunctionName")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[ServiceBus("myqueueortopicname", Connection = "ServiceBusConnection")] IAsyncCollector<string> messages)
I'm trying to make the service bus queue name to be configurable and to be taken from Environment.GetEnvironmentVariable("MyMessageBusQueueName")
With
[ServiceBus(Environment.GetEnvironmentVariable("MyMessageBusQueueName"), Connection = "ServiceBusConnection")] IAsyncCollector<string> messages)`
local.Settings.json:
{
"IsEncrypted": false,
"Values": {
"MyMessageBusQueueName": "myqueueortopicname",
"ServiceBusConnection": "..."
},
"ConnectionStrings": {}
}
But I'm having an error of:
An attribute argument must be a constant expression, typeof expression
or array
You need to use the binding expression by wrapping the environment variable name with %. Define the queue name as %MyMessageBusQueueName% which would bind to environment variable
[ServiceBus("%MyMessageBusQueueName%", Connection = "ServiceBusConnection")] IAsyncCollector<string> messages)
Read about binding expression at Microsoft documentation ---here.
I'm developing an application where IOT devices are connected with the Azure IOT Hub. and its realtime data can be visible on the web view. However, I'm facing an error, I'm trying to bind the data Azure function with SignalR, but when I run the application I receive the following error message.
The listener for function 'SignalR' was unable to start. Microsoft.Azure.EventHubs.Processor: Encountered error while fetching the list of EventHub PartitionIds. System.Private.CoreLib: The link address '$management' did not match any of the expected formats.
Error Description Image
I've tried everything to fix it but failed every time. I'd really appreciate if someone would help me find the solution to this problem.
Here is the script I'm using from this link
Here is my SignalR.cs class
public static class SignalR
{
[FunctionName("SignalR")]
public static async Task Run(
[IoTHubTrigger("messages/events", Connection = "IoTHubTriggerConnection", ConsumerGroup = "$Default")]EventData message,
[SignalR(HubName = "broadcast")]IAsyncCollector<SignalRMessage> signalRMessages,
ILogger log)
{
var deviceData = JsonConvert.DeserializeObject<DeviceData>(Encoding.UTF8.GetString(message.Body.Array));
deviceData.DeviceId = Convert.ToString(message.SystemProperties["iothub-connection-device-id"]);
log.LogInformation($"C# IoT Hub trigger function processed a message: {JsonConvert.SerializeObject(deviceData)}");
await signalRMessages.AddAsync(new SignalRMessage()
{
Target = "notify",
Arguments = new[] { JsonConvert.SerializeObject(deviceData) }
});
}
}
Here is my SignalRConnection.cs class
public static class SignalRConnection
{
[FunctionName("SignalRConnection")]
public static SignalRConnectionInfo Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
[SignalRConnectionInfo(HubName = "broadcast")] SignalRConnectionInfo info,
ILogger log) => info;
}
Here is my local.settings.json file
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"AzureSignalRConnectionString": "",
"MSDEPLOY_RENAME_LOCKED_FILES": 1,
"IoTHubTriggerConnection": ""
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "*"
}
}
for IoTHubTriggerConnection, I'm using the connection string of iothubjohnsoncontrol (displayed in image below).
IOT Hub Keys Image
for AzureSignalRConnectionString, I'm using the connection string of signalrjohnsoncontrol (displayed in image below).
SignalR Keys Image
Could you please check if you have given EventHub Compatible name and EventHub compatible connections string from here
Please try replacing messages/events with EventHub-Compatible name and IoTHubTriggerConnection as EventHub compatible endpoint from portal.
Almost similar discussion here :
https://github.com/Azure/azure-event-hubs-dotnet/issues/103
I have a usecase like that to Push Iot data to Azure data explorer and this is what my Function looks like
Iot Hub Connection string which is EventHub compatibale
Hope this helps.
I have an azure function taking in messages from an Azure service bus queue and sending documents to cosmosDB. I'm using Azure functions 1.x:
public static class Function1
{
[FunctionName("Function1")]
public static void Run([ServiceBusTrigger("ServiceBusQueue", AccessRights.Manage, Connection = "ServiceBusQueueConnection")]BrokeredMessage current, [DocumentDB(
databaseName: "DBname",
collectionName: "Colname",
ConnectionStringSetting = "CosmosDBConnection")]out dynamic document, TraceWriter log)
{
document = current.GetBody<MyObject>();
log.Info($"C# ServiceBus queue triggered function processed the message and sent to cosmos");
}
}
This inserts to cosmos successfully, but when updating I get errors:
Microsoft.Azure.Documents.DocumentClintException: Entity with the specified id already exists in the system.
They key I'm trying to update on is the partition key of that collection.
I saw this question: Azure function C#: Create or replace document in cosmos db on HTTP request
But It seems like my usage is similar to the one in Matias Quarantas answer. Also he mentioned that using an out parameter causes an upsert on cosmos.
How can I create this "upsert" function, while still using azure function 1.x?
The binding does indeed do an Upsert operation.
I created this sample Function that takes an Http payload (JSON) and stores it in Cosmos DB as-is:
[FunctionName("Function1")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req,
[DocumentDB("MyDb", "MyCollection", ConnectionStringSetting = "MyCosmosConnectionString")] out dynamic document,
TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
dynamic data = req.Content.ReadAsAsync<object>().GetAwaiter().GetResult();
document = data;
return req.CreateResponse(HttpStatusCode.OK);
}
If I send a JSON payload to the Http endpoint, the output binding works as expected:
When I check the Data Explorer, I see:
If I send a second payload, this time, adding a property (same id):
The Data Explorer shows the document was updated, with the same Function code:
Can you add the full Exception/Error trace? Is your Service Bus Message including an "id"? Is your collection partitioned?
If your collection is partitioned and you are changing the value of the Partition key property, then the binding won't update the existing document, it will create a new one because the Upsert operation won't find an existing document (based on the id/partition key). But it won't throw an exception.
I want to make an Azure Function that takes a JSON body passed to it and inserts this document in to an Azure COSMOSDB instance.
To do so, I created this function in the Azure Functions Portal:
And implement the function like so:
#r "Newtonsoft.Json"
using Newtonsoft.Json.Linq;
using System.Net;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, object outputDocument)
{
var requestContent = await req.Content.ReadAsStringAsync();
log.Verbose($#"Received request:\n{requestContent}");
var newDoc = JObject.Parse(requestContent);
newDoc["Id"] = Guid.NewGuid().ToString();
newDoc["shardKey"] = newDoc.Value<string>(#"Id").Substring(8);
outputDocument = newDoc;
return req.CreateResponse(System.Net.HttpStatusCode.Created);
}
In the portal, I put in an easy sample doc:
{
"prop1": 2,
"prop2": "2017-02-20",
}
and click 'Run'
I'm immediately met with
as an overlay in the portal IDE along with
{
"id": "145ee924-f824-4064-8364-f96dc12ab138",
"requestId": "5a27c287-2c91-40f5-be52-6a79c7c86bc2",
"statusCode": 500,
"errorCode": 0,
"message": "'UploadDocumentToCosmos' can't be invoked from Azure WebJobs SDK. Is it missing Azure WebJobs SDK attributes?"
}
in the log area.
There seems to be nothing I can do to fix the issue, yet I sure feel like I'm doing everything right.
What do I need to do to simply take a JSON object as an HTTP Request to an Azure Function, and insert/upsert said object in to an Azure Cosmos DB instance??
For async functions you should use IAsyncCollector:
public static async Task<HttpResponseMessage> Run(
HttpRequestMessage req, TraceWriter log,
IAsyncCollector<object> outputDocuments)
{
...
await outputDocuments.AddAsync(newDoc);
}
Can you try adding out to dynamic outputDocument?
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, out dynamic outputDocument)