I have an Azure Function that I created in the Azure portal and now want to recreate it using the visual studio azure tooling associated with VS2017 Preview.
My function is Timer triggered, and also has an input binding for Azure DocumentDB (with a query) and an output binding to an Azure Service Bus queue.
Here's the functions.json definition from the portal:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
},
{
"type": "serviceBus",
"name": "outputQueue",
"queueName": "test-output-requests",
"connection": "send-refresh-request",
"accessRights_": "Send",
"direction": "out"
},
{
"type": "documentDB",
"name": "incomingDocuments",
"databaseName": "test-db-dev",
"collectionName": "TestingCollection",
"sqlQuery": "select * from c where c.docType = \"Test\"",
"connection": "my-testing_DOCUMENTDB",
"direction": "in"
}
],
"disabled": false
}
In VS2017, I create an Azure Function project, then a Azure function using the TimerTriggered template:
public static void Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, TraceWriter log, ICollector<dynamic> outputQueue, IEnumerable<dynamic> incomingDocuments)
{
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
//Inspect incomingDocuments .. push messages to outputQueue
}
Running locally, the timer is triggered as expected - but how do I recreate the input and output bindings in code? I'm not sure what attributes I should use, and what I need in json config files to wire it up.
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
Related
I'm trying to compile a Function on the Visual Code Studio but I'm getting the following error:
Function.js
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
},
{
"type": "table",
"direction": "out",
"name": "outputTable",
"tableName": "contmaticTable",
"connection": "degustfunction9451_STORAGE"
}
]
}
The error begins after create a out bidding (table)
My code snippet:
module.exports = function (context, myTimer,outputTable) {
var timeStamp = new Date().toISOString();
....
}
Bidings:
There were breaking changes in 2.0.12050. You can refer to this page: https://github.com/Azure/app-service-announcements/issues/129
The Azure Storage bindings (blob, queues and tables triggers and bindings) were previously part of the runtime, but moving forward, will need to be explicitly installed.
To temporarily avoid impact, you can pin your Function App to the previous version of the runtime by updating the app setting FUNCTIONS_EXTENSION_VERSION to 2.0.11961-alpha
You can modify the FUNCTIONS_EXTENSION_VERSION in visual studio code in your function's "Application Settings" or modify it on Azure portal by clicking "Configuration"(then under "Application settings"). Change it from "~2" to "~2.0.11961-alpha".
I have the following C# function code:
[FunctionName("UpdateCohortsByTenantFunction")]
[return: Queue("my-queue", Connection = "MyStorage")]
//note - I have tried both method decoration and parameter decoration
public static async Task Run([TimerTrigger("* * * * * *")]TimerInfo myTimer, IAsyncCollector<AudienceMessage> output)
{
//some logic
foreach (var audience in audiences)
{
await output.AddAsync(new AudienceMessage
{
AudienceId = audience.Id,
TenantId = tenant.Id
});
}
}
Which produces the following function.json:
{
"generatedBy": "Microsoft.NET.Sdk.Functions.Generator-1.0.6",
"configurationSource": "attributes",
"bindings": [
{
"type": "timerTrigger",
"schedule": "* * * * * *",
"useMonitor": true,
"runOnStartup": false,
"name": "myTimer"
}
],
"disabled": false,
"scriptFile": "../bin/MyApp.App.Tasks.Functions.dll",
"entryPoint": "MyApp.App.Tasks.Functions.UpdateCohortsByTenantFunction.Run"
}
According to the documentation here the json output should contain an binding to my queue with an "out" direction. Ie:
{
"type": "queue",
"direction": "out",
"name": "$return",
"queueName": "outqueue",
"connection": "MyStorageConnectionAppSetting",
}
When I try to run the queue via the npm tools (config described here), I get the following error:
Run: Microsoft.Azure.WebJobs.Host: Error indexing method 'UpdateCohortsByTenantFunction.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'output' to type IAsyncCollector`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.).
The documentation contains no references to binding via startup code. My understanding is that this is done via the attributes described in the Microsoft documentation linked above, and in my example code, but the error message suggests otherwise.
You should decorate your parameter with attribute, not return value:
public static async Task Run(
[TimerTrigger("* * * * * *")]TimerInfo myTimer,
[Queue("my-queue", Connection = "MyStg")] IAsyncCollector<AudienceMessage> output)
No output binding in function.json is to be expected. Attribute-defined bindings are not transferred to generated function.json. They will still work, don't worry.
I have an Azure Timer Trigger Function that should do some calculations and write the results to a json file in a pre-existing blob. How do I reference the pre-existing blob from within the Timer Triggered function?
I can't seem to find any documentation that provides a code sample. Can someone provide one?
First, you need to update your function.json configuration file, to bind the blob to the CloudBlockBlob instance you'll be using in your .csx code. You can edit it in Azure Portal via the "Integrate" option (the one with the lighting icon) under your function, in the Function Apps menu. On the top right of that page is a link that reads "Advanced Editor". Clicking that link will take you to your funciton's function.json file:
You'll see a JSON array named "bindings" that contains a JSON object that configures your timer. You'll want to add another JSON object to that array to bind your blob to a CloudBlockBlob instance that you'll be referencing in your function. Your function.json file will look something like this:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
},
{
"type": "blob",
"name": "myBlob",
"path": "your-container-name/your_blob_filename.json",
"connection": "AzureWebJobsStorage",
"direction": "inout"
}
],
"disabled": false
}
Now you just need to update your function's Run method's signature. It looks like this by default:
public static void Run(TimerInfo myTimer, TraceWriter log)
Add your blob variable to the end of that signature (and also add the necessary includes):
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
public static void Run(TimerInfo myTimer, TraceWriter log, CloudBlockBlob myBlob)
And you're all set! "myBlob" is bound to the blob "your_blob_filename.json" in your "your-container-name" container.
Is it possible to invoke cosmos db trigger in azure pipeline? Pipeline is just copy data from azrue storage to cosmos db collection and it is necessary to invoke pre trigger. How to specify trigger id for copy activity?
From what you are saying, you might solve this by using Azure Functions with a Blob Trigger and a DocumentDB output binding.
With a functions.json similar to:
{
"disabled": false,
"bindings": [
{
"name": "myBlob",
"type": "blobTrigger",
"direction": "in",
"path": "<name-of-the-folder-where-files-get-uploaded>",
"connection":"MyStorageAccount"
},
{
"name": "documentToSave",
"type": "documentDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"createIfNotExists": true,
"connection": "MyAccount_COSMOSDB",
"direction": "out"
}
]
}
And the function body could be something like:
// Blob trigger binding to a CloudBlockBlob
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Blob;
public static void Run(CloudBlockBlob myBlob, out object documentToSave, TraceWriter log)
{
// some logic to read the blob and parse it
documentToSave = new {
id = "some value",
.. other properties here
};
}
I am trying to use Azure function with to invoke the same function with different time and different param(url).
I didn't find any good example that shows how to pass some data. I want to pass link to function.
My code is:
var rp = require('request-promise');
var request = require('request');
module.exports = function (context //need to get the url) {
and the function
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 0 */1 * * *"
}
],
"disabled": false
}
If your settings are relatively static (but you still don't want to hard code them), you may use app settings to store them, and then read e.g.
let url = process.env['MyUrl'];
If URL should be determined per request, you may use HTTP trigger and read the URL from query parameters:
let url = req.query.myurl;
I'm not sure what exactly you are trying to achieve with parameterized timer-triggered function.
Another possibility is if your parameters are stored somewhere in e.g. Azure Document DB (Cosmos).
You could still use a TimerTrigger to invoke the function, and include a DocumentDB input binding allowing you to query for the specific parameter values needed to execute the function.
Here's a C# example triggered by Timer, with a DocumentDB input binding. Note: I'm using the latest VS2017 Preview tooling for Azure functions.
[FunctionName("TimerTriggerCSharp")]
public static void Run(
[TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, TraceWriter log,
[DocumentDB("test-db-dev", "TestingCollection", SqlQuery = "select * from c where c.doc = \"Test\"")] IEnumerable<dynamic> incomingDocuments)
{..}
With the following binding json:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 */5 * * * *"
},
{
"type": "documentDB",
"name": "incomingDocuments",
"databaseName": "test-db-dev",
"collectionName": "TestingCollection",
"sqlQuery": "select * from c where c.docType = \"Test\"",
"connection": "my-testing_DOCUMENTDB",
"direction": "in"
}
],
"disabled": false
}