Documentdb With Azure Functions

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;}
}

enter image description here

enter image description here

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;}
}

enter image description here

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.

enter image description here

I tried to run the same code in Azure and it doesn't show have any difference.

enter image description here

As I know , Java Azure Function is still a preview version and I find the Annotation against Cosmos db for java is N/A.

enter image description here

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();
}

}

enter image description here

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.

enter image description here

If I specify invalid JSON in the request body, I will get the same error as yours.

enter image description here

How to bind DocumentDB input to Azure Function?

  1. Add reference to following nuget pacakge
    https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.DocumentDB/
  2. Add using Microsoft.Azure.WebJobs
  3. Update the documentDb Parameter as follows (Add other properties as well)

    [DocumentDB(ConnectionStringSetting = "")]IEnumerable<dynamic> incomingDocuments
  4. 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



Leave a reply



Submit