Azure http function and DocumentDB
Trying to build a couple simple http Azure functions. One would take a POST from a web app, containing a JSON body, and save that as a document in CosmosDB (DocumentDB).
To store data in Cosmos DB from HttpTrigger Azure functions app, you can refer to the following sample code that works fine on my side.
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, out object taskDocument, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
MyData md=req.Content.ReadAsAsync<MyData>().Result;
taskDocument = new {
name = md.name,
task = md.task,
duedate = md.duedate
};
if (name != "") {
return req.CreateResponse(HttpStatusCode.OK);
}
else {
return req.CreateResponse(HttpStatusCode.BadRequest);
}
}
public class MyData{
public string name { get; set;}
public string task { get; set;}
public string duedate { get; set;}
}
The other sends a GET request with a parameter, which reads that document from the database and returns it as JSON.
To retrieve data from Cosmos DB and return it as JSON via Azure functions app, please refer to the following sample.
function.json
{
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "documents/{name}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "inputDocument",
"databaseName": "xxxdocumentdbtest",
"collectionName": "testcoll",
"sqlQuery": "SELECT * FROM c where c.name = {name}",
"connection": "xxxx_DOCUMENTDB",
"direction": "in"
}
],
"disabled": false
}
run.csx
#r "Newtonsoft.Json"
using System.Net;
using Newtonsoft.Json;
public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<MyData> inputDocument, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
MyData md = inputDocument.FirstOrDefault();
log.Info(md.task);
var val = JsonConvert.SerializeObject(md);
return req.CreateResponse(HttpStatusCode.OK, val);
}
public class MyData{
public string name { get; set;}
public string task { get; set;}
public string duedate { get; set;}
}
Is it possible to configure Azure C# function DocumentDB attribute arguments?
You need to do this:
[DocumentDB("%database%", "%collection%", ConnectionStringSetting = "CosmosDBConnection")]
and then define settings with corresponding names (without %
).
Azure Functions and DocumentDB triggers
You could refer to the following code sample to create document with the trigger enabled in Azure Functions.
using System;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
public static void Run(string myQueueItem, TraceWriter log)
{
string EndpointUri = "https://{documentdb account name}.documents.azure.com:443/";
string PrimaryKey = "{PrimaryKey}";
DocumentClient client = new DocumentClient(new Uri(EndpointUri), PrimaryKey);
client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri("{databaseid}", "{collenctionid}"), new MyChunk { MyProperty = "hello" },
new RequestOptions
{
PreTriggerInclude = new List<string> { "YourTriggerName" },
}).Wait();
log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
}
public class MyChunk
{
public string MyProperty { get; set; }
}
Note: for using Microsoft.Azure.DocumentDB NuGet package in a C# function, please upload a project.json file to the function's folder in the function app's file system.
project.json
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.Azure.DocumentDB": "1.13.1"
}
}
}
}
Besides, please make sure you have created triggers in your DocumentDB, for details about creating triggers, please refer to this article.
Output Java Function to DocumentDB
I tried to test your java azure function code on my side.
Java code:
@FunctionName("doc")
@DocumentDBOutput(name = "testdoc",
createIfNotExists = true,
databaseName = "db",
collectionName="coll",
connection = "CosmosDBConnectionString")
public String functionHandler(
@TimerTrigger(name = "timerInfo", schedule = "*/30 * * * * *")
String timerInfo,
final ExecutionContext executionContext) {
String randomString=UUID.randomUUID().toString();
executionContext.getLogger().info("Insert obj documentDB: " + randomString);
Document document=new Document();
document.set("id",randomString);
document.set("name","Jay!!!");
return document.toString();
}
function.json
{
"scriptFile" : "..\\fabrikam-functions-1.0-SNAPSHOT.jar",
"entryPoint" : "com.fabrikam.functions.Function.functionHandler",
"bindings" : [ {
"type" : "timerTrigger",
"name" : "timerInfo",
"direction" : "in",
"schedule" : "*/30 * * * * *"
}, {
"type" : "documentdb",
"name" : "$return",
"direction" : "out",
"databaseName" : "db",
"collectionName" : "coll",
"connection" : "CosmosDBConnectionString",
"createIfNotExists" : true
} ],
"disabled" : false
}
The Azure Function runs successfully locally ,but the documents are not be passed into Document DB, as same as you.
I tried to run the same code in Azure and it doesn't show have any difference.
As I know , Java Azure Function is still a preview
version and I find the Annotation
against Cosmos db
for java is N/A
.
You could check the webjob dashboard to verify if any error log exist in the table storage which is configured in the AzureWebJobsStorage
.
In addition , I suggest you a workaround that you could call the Document DB Java SDK in your TimerTrigger. Please refer to the snippet of code as below:
private static final String account = "***";
private static final String key = "***";
private static DocumentClient client = new DocumentClient("***",
key, ConnectionPolicy.GetDefault(),
ConsistencyLevel.Session);
@FunctionName("doc")
public String functionHandler(
@TimerTrigger(name = "timerInfo", schedule = "*/5 * * * * *")
String timerInfo,
final ExecutionContext executionContext) {
try {
String randomString = UUID.randomUUID().toString();
executionContext.getLogger().info("Insert obj documentDB: " + randomString);
Document document = new Document();
document.set("id", randomString);
document.set("name", "Jay!!!");
client.createDocument("dbs/db/colls/coll",document,null,false);
return "Insert Success id: "+ randomString;
} catch (Exception e) {
executionContext.getLogger().info(e.toString());
return e.toString();
}
}
Hope it helps you.
Azure Functions Http trigger - DocumentDB out Integration Microsoft.Azure.Documents.Client: Value cannot be null
Both of your function.json
and code of index.js
are OK. You need to feed valid JSON string into req.body
.
Here is my testing screenshot.
If I specify invalid JSON in the request body, I will get the same error as yours.
How to bind DocumentDB input to Azure Function?
- Add reference to following nuget pacakge
https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.DocumentDB/ - Add
using Microsoft.Azure.WebJobs
Update the documentDb Parameter as follows (Add other properties as well)
[DocumentDB(ConnectionStringSetting = "")]IEnumerable<dynamic> incomingDocuments
Update the serviceBus Parameter as follows
[ServiceBus("test-output-requests",Connection = "ConnectionValue")]
Verify the generated function.json in the bin/functionName/function.json
Thanks,
Naren
Send SqlQuery in Azure Function's DocumentDB Attribute
You need to reference 1.1.0-beta
version of Microsoft.Azure.WebJobs.Extensions.DocumentDB
NuGet package (or later).
In that version SqlQuery
is a valid parameter of DocumentDB
attribute. You code compiles for me, if I remove $
sign before select
string:
[DocumentDB("FunctionJunctionDemo", "Demo", SqlQuery = "select * from c where c.Id = {Id}")]
You don't need $
- it's used for string interpolation in C#, not something you want to do here.
Related Topics
Declare Properties to Ignore in Entities Interface (Ef Core)
How to Use a Class from One C# Project With Another C# Project
Error Reading Jobject from Jsonreader. Current Jsonreader Item Is Not an Object: Startarray. Path
Make a File Open in Browser Instead of Downloading It
Fastest Way to Find Strings in a File
How to Trigger Event When a Variable'S Value Is Changed
Adding an Incremental Number to Duplicate String
Using Linq to Remove Elements from a List<T>
Check If Datetime Is a Weekend or a Weekday
Empty String Not Being Converted to Null When Passing Json Object to Controller
Unexpected Character Encountered While Parsing Value
C# How to Check If a Url Exists/Is Valid
Checking Whether a Number Contains Numbers 1 to N as Factors
Where Is the Postasjsonasync Method in ASP.NET Core
How to Get the Specific Column in Excel Worksheet Using Documentformat.Openxml C#