# Friday, 30 November 2018

Given an Azure Function, you may wish to change the URL that points to this function. There are several reasons to do this:

  1. Make the URL simpler
  2. Make the URL more readable
  3. Make the URL conform to your organization's standards

To reassign a Function's URL, you will need to know the existing URL. To find this, select the Function and click the "Get function URL" link, as shown in Fig. 1.

FP01-GetFunctionUrl
Fig. 1

The Function URL dialog displays, as shown in Fig. 2.

FP02-FunctionUrl
Fig. 2

Click the [Copy] icon to copy this URL to your clipboard. You may wish to paste this into a text document or another safe place for later use.

Each Azure Function App contains a "Proxies" section, as shown in Fig. 3.

FP03-Proxies
Fig. 3

Click the [+] icon to display the "New proxy" blade, as shown in Fig. 4.

FP04-Proxy
Fig. 4

At the "Name" field, enter a name to identify this proxy. I like to include the name of the original function in this name, to make it easy to track to its source.

At the "Route template" field, enter a template for the new URL. This is everything after the "https://" and the domain name. If the function accepts parameters, you will need to add these and surround them with curly brackets: "{" and "}".

At the "Allowed HTTP methods" dropdown, select "All methods" or check only those methods you wish your new URL to support.

At the "Backend URL" field, enter the full original URL copied earlier to your clipboard. If the function accepts parameters, you will need to add these and surround them with curly brackets: "{" and "}". The parameter name here must match the parameter name in the "Route template" field.

An example

For example, if I created a Function with an HTTPTrigger and accepted all the defaults (as described here), you will have a function that accepts a querystring parameter of "name" and outputs "Hello, " followed by the value of name.

My original function URL looked similar to the following:

https://dgtestfa.azurewebsites.net/api/HttpTrigger1?code=idLURPj58mZrDdkAh9LkTkkz2JZRmp6/ru/DQ5RbotDpCtg/WY/pRw==

So, I entered the following values into the "New Proxy" blade:

Name: HttpTrigger1Proxy
Route template: welcome/{name}
Allowed HTTP methods: All methods
Backend URL: https://dgtestfa.azurewebsites.net/api/HttpTrigger1?code=idLURPj58mZrDdkAh9LkTkkz2JZRmp6/ru/DQ5RbotDpCtg/WY/pRw==&name={name}

With these settings, I can send a GET or POST request to the following url:

https://dgtestfa.azurewebsites.net/welcome/David

and receive the expected response:

Hello, David

This new URL is much simpler and easier to remember than the original one.

In this article, I showed you how to create a proxy that redirects from a new URL to an existing Azure Function.

Friday, 30 November 2018 09:43:00 (GMT Standard Time, UTC+00:00)
# Thursday, 29 November 2018

GCast 24:

Azure Function CosmosDB Binding

Using the CosmosDB binding in an Azure Function allows you to read and write documents in an Azure CosmosDB database without writing code.

Thursday, 29 November 2018 09:22:00 (GMT Standard Time, UTC+00:00)
# Wednesday, 28 November 2018

Setting up continuous deployment of an Azure Function from GitHub  is straightforward.

In this article, I already had an Azure Function (created using Visual Studio) in a GitHub  repository and an empty Azure Function App.

See this article for information on GitHub

See this article to learn how to create an Azure Function App.

Open the Azure Function App in the Azure portal, as shown in Fig. 1.

DF01-FunctionApp-big
Fig. 1

Click the "Platform features" link (Fig. 2) to display the "Platform features" page, as shown in Fig. 3.

DF02-PlatformFeaturesLink
Fig. 2

DF03-PlatformFeatures
Fig. 3

Under "Code Deployment", click the "Deployment Center" link to open the "Deployment Center" page, as shown in Fig. 4.

DF04-DeploymentCenter
Fig. 4

On the "Deployment Center" page, select the "GitHub " tile and click the [Continue] button, as shown in Fig. 5.

DF05-DeploymentCenterContinue
Fig. 5

The wizard advances to the "Configure" page of the "Deployment Center" wizard, as shown in Fig. 6.

DF06-ConfigureDeployment
Fig. 6

At the "Organization" dropdown, select the GitHub  account where your code resides. If you don't see the account, you may need to give your Azure account permission to view your GitHub  repository.

At the "Repository" dropdown, select the code repository containing your Azure Functions.

At the "Branch" dropdown, select the code branch you wish to deploy whenever a change is pushed to the repository. I almost always select "master" for this.

Click the [Continue] button to advance to the "Summary" page of the "Deployment Center" wizard, as shown in Fig. 7.

DF07-Summary
Fig. 7

On the "Summary" page, review your choices and click the [Finish] button if they are correct. (If they are not correct, click the [Back] button and make the necessary corrections.

In a few minutes, the function or functions in your repository will appear under your Function App in the Azure portal, as shown in Fig. 8.

DF08-Function
Fig. 8

Any future changes pushed to the repository will automatically be added to the Function App.

For example, I can open my Visual Studio project and add a second function, as shown in Fig. 9

DF09-AddNewFunction
Fig. 9

After testing the change, I can push it to my GitHub  repository with the following commands:

git add .
git commit -m "Added a new function"
git push origin master

Listing 1

Because a webhook was added to my GitHub  repository, this change will be pushed to my Azure Function App. Fig. 10 shows the Function app a few minutes after I pushed my change to GitHub .

DF10-FunctionAppAfterPush
Fig. 10

In this article, you learned how to configure continuous deployment of your Azure Function App from a GitHub repository.

Wednesday, 28 November 2018 08:33:00 (GMT Standard Time, UTC+00:00)
# Tuesday, 27 November 2018

In a recent article, I showed how to create a Durable Azure Function. If you are unfamiliar with Durable Functions, I recommend you read that article first.

In that article, the Durable Function called 3 Activity Functions in sequence. No Function executed until the Function before it completed. Sometimes, it is important that Functions execute in a certain order. But sometimes it does not matter in which order a Function executes - only that they each complete successfully before another Activity Function is called. In these cases, executing sequentially is a waste of time. It is more efficient to execute these Azure Functions in parallel.

In this article, I will show how to create a durable function that executes three Activity Functions in parallel; then waits for all 3 to complete before executing a fourth function.
 
Fig. 1 illustrates this pattern.

PD01-ParallelDurableFunctionFlow
Fig. 1
 
As we noted in the earlier article, a Durable function is triggered by a starter function, which is in turn triggered by an HTTP request, database change, timer, or any of the many triggers supported by Azure Functions, as shown in Fig. 2.

PD02-DurableFunctionTrigger
Fig. 2

I created 4 Activity Functions that do nothing more than write a couple messages to the log (I use LogWarning, because it causes the text to display in yellow, making it easier to find); delay a few seconds (to simulate a long-running task); and return a string consisting of the input string, concatenated with the name of the current function. The functions are nearly identical: Only the Function Name, the message, and the length of delay are different.

The 4 functions are shown below:

    public static class Function1
     {
         [FunctionName("Function1")]
         public static async Task<string> Run(
             [ActivityTrigger] string msg,
             ILogger log)
         {
             log.LogWarning("This is Function 1");
             await Task.Delay(15000);
             log.LogWarning("Function 1 completed");
             msg += "Function 1";
            return msg;
        }
    }
  

Listing 1

    public static class Function2 
    { 
        [FunctionName("Function2")] 
        public static async Task<string> Run( 
            [ActivityTrigger] string msg, 
            ILogger log) 
        { 
             log.LogWarning("This is Function 2"); 
            await Task.Delay(10000); 
            log.LogWarning("Function 2 completed"); 
            msg += "Function 2"; 
            return msg; 
        } 
    }
  

Listing 2

    public static class Function3 
     { 
        [FunctionName("Function3")] 
        public static async Task<string> Run( 
            [ActivityTrigger] string msg, 
            ILogger log) 
        { 
            log.LogWarning("This is Function 3"); 
            await Task.Delay(5000); 
             log.LogWarning("Function 3 completed"); 
            msg += "Function 3"; 
            return msg; 
        } 
    }
  

Listing 3

    public static class Function4 
    { 
        [FunctionName("Function4")] 
        public static async Task<string> Run( 
             [ActivityTrigger] string msg, 
            ILogger log) 
         { 
            log.LogWarning("This is Function 4"); 
             int secondsDelay = new Random().Next(8, 12); 
            await Task.Delay(1000); 
            log.LogInformation("Function 4 completed"); 
            msg += "\n\rFunction 4"; 
            return msg; 
        } 
    }
  

Listing 4

We use the Parallel Task library to launch the first 3 functions and have them run in parallel; then, wait until each of the first 3 complete before executing the 4th Activity Function.

Listing 5 shows this code in our Durable Orchestration function.

    public static class DurableFunction1 
    { 
        [FunctionName("DurableFunction1")] 
         public static async Task<IActionResult> Run( 
            [OrchestrationTrigger] DurableOrchestrationContext ctx, 
            ILogger log) 
        { 
            var msg = "Durable Function: "; 
            var parallelTasks = new List<Task<string>>(); 
             Task<string> task1 = ctx.CallActivityAsync<string>("Function1", msg); 
            parallelTasks.Add(task1); 
            Task<string> task2 = ctx.CallActivityAsync<string>("Function2", msg); 
            parallelTasks.Add(task2); 
            Task<string> task3 = ctx.CallActivityAsync<string>("Function3", msg); 
             parallelTasks.Add(task3);

            await Task.WhenAll(parallelTasks);

            // All 3 Activity functions finished 
            msg = task1.Result + "\n\r" + task2.Result + "\n\r" + task3.Result;

            // Use LogWarning, so it shows up in Yellow, making it easier to spot 
            log.LogWarning($"All 3 Activity functions completed for orchestration {ctx.InstanceId}!");

            msg = await ctx.CallActivityAsync<string>("Function4", msg); 
            log.LogWarning(msg);

            return new OkObjectResult(msg); 
        } 
    }
  

Listing 5

We create a new List of Tasks and add each activity to that list:

var msg = "Durable Function: ";
var parallelTasks = new List<Task<string>>();
Task<string> task1 = ctx.CallActivityAsync<string>("Function1", msg);
parallelTasks.Add(task1);
Task<string> task2 = ctx.CallActivityAsync<string>("Function2", msg);
parallelTasks.Add(task2);
Task<string> task3 = ctx.CallActivityAsync<string>("Function3", msg);
parallelTasks.Add(task3);

The following line tells the system to wait until all 3 tasks in that list are completed.

await Task.WhenAll(parallelTasks);

When all 3 tasks complete, we resume the program flow, calling the 4th Activity and logging the output:

log.LogWarning($"All 3 Activity functions completed for orchestration {ctx.InstanceId}!");
msg = await ctx.CallActivityAsync<string>("Function4", msg);
log.LogWarning(msg);

As in the previous article, we launch this Durable Orchestration Function with a starter function (in this case a function with an HTTP trigger), as shown in Listing 6 below.

    public static class StarterFunction1 
    { 
        [FunctionName("StarterFunction1")] 
        public static async Task<HttpResponseMessage> Run( 
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] 
            HttpRequestMessage req, 
            [OrchestrationClient] DurableOrchestrationClient starter, 
            TraceWriter log) 
        { 
             log.Info("About to start orchestration");

            var orchestrationId = await starter.StartNewAsync("DurableFunction1", log); 
            return starter.CreateCheckStatusResponse(req, orchestrationId); 
        } 
    }
  

Testing the Orchestration

We can test this orchestration by running the solution, which displays the HTTP Trigger URL, as shown in Fig. 3

PD003-StartFunction
Fig. 3

We can then open a browser, type the HTTP Trigger URL in the address bar, and press [ENTER] to trigger the function, as shown in Fig. 4

PD004-TriggerFunction
Fig. 4

Switch back to the function output to view the messages as they scroll past. You should see output from each of the first 3 functions (although not necessarily in the order called), followed by a message indicating the first 3 are complete; then output from Function 4. This is shown in Fig. 5.

PD005-FinalOutput
Fig. 5

You can view this project under “Durable Functions” in this GitHub repository.

In this article, I showed how to create a Durable Orchestration Function that launches activity functions that run in parallel.

Tuesday, 27 November 2018 07:29:00 (GMT Standard Time, UTC+00:00)
# Friday, 23 November 2018

Azure Functions provide a simple way to deploy code in a scalable, cost-effective way.

By default, Azure Functions are stateless, which makes it difficult to create complex workflows with basic Azure functions - particularly long-running workflows, such as those that require human interaction.

A Durable Azure Function maintains state for a long time, without having to stay in memory, making it ideal for orchestrations. Stateful information is stored in an Azure Storage Account when the the process terminates. This saves you money, because the default pricing model for Azure functions only charges you while the function is running.

A Durable Function is not triggered in the same way as other Azure Functions (via HTTP, queue, database changes, timer, etc.) Rather, it is called from a "starter" function, which can be triggered in the usual way.

Rather than placing all logic within a single Durable Function, it usually makes more sense to split tasks into individual Activity Functions and have the Durable Function manage these. The most simple Durable Function would simply call multiple activities in sequence. A diagram of this is shown in Fig. 1.

DF01-DurableFunctionFlow
Fig. 1

You can create a Function App for an Azure Durable function in Visual Studio in the same way you create any function - by selecting File | New Project from the menu and selecting "Azure Functions" from the Project Templates dialog, as shown in Fig. 2.

DF02-NewFunctionProject
Fig. 2

Select "Azure Functions v2" from the top dropdown and HttpTrigger" from the list of templates, as shown in Fig. 3; then, click the [OK] button to create the solution and project.

DF03-FunctionTemplate
Fig. 3

The new project contains a function named "Function1". Right-click this function in the Solution Explorer and rename it to "StarterFunction", as shown in Fig. 4.

DF04-RenameFunction
Fig. 4

Open StarterFunction.cs and change the first line of the class from

[FunctionName("Function1")]

to

[FunctionName("StarterFunction")]

Now, you can add a Durable Function to the project. Right-click the project in the Solution Explorer and select Add | New Azure Function from the context menu, as shown in Fig. 5.

DF05-AddNewAzureFunction
Fig. 5

Name the new function "DurableFunction1", as shown in Fig. 6.

DF06-AddDurableFunction
Fig. 6

At the next dialog, select "Durable Function Orchestration" from the list of triggers and click the [OK] button to create the function, as shown in Fig. 7.

DF07-DurableFunctionsOrchestration
Fig. 7

This Durable Function will manage 3 functions, calling each one sequentially. To the project, add 3 new functions named "Function1", "Function2", and "Function3". It does not matter which trigger you choose, because we are going to overwrite the trigger. Paste the code below into each function:

    public static class Function1 
    { 
        [FunctionName("Function1")] 
        public static async Task<string> Run( 
            [ActivityTrigger] string msg, 
            ILogger log) 
        { 
            log.LogWarning("This is Function 1");

            await Task.Delay(10000); 
            msg += "Function1 done; "; 
            return msg; 
        } 
    }
  

Listing 1

    public static class Function2 
    { 
        [FunctionName("Function2")] 
        public static async Task<string> Run( 
             [ActivityTrigger] string msg, 
            ILogger log) 
        { 
            log.LogWarning("This is Function 2");

            await Task.Delay(10000); 
            msg += "Function2 done; "; 
            return msg; 
        } 
    }
  

Listing 2

    public static class Function3 
    { 
        [FunctionName("Function3")] 
        public static async Task<string> Run( 
            [ActivityTrigger] string msg, 
            ILogger log) 
        { 
            log.LogWarning("This is Function 3");

            await Task.Delay(10000); 
            msg += "Function3 done; "; 
            return msg; 
        } 
    }
  

Listing 3

As you can see, each function essentially does the same thing: log a brief message; wait 10 seconds; then, return a string consisting of the string passed in with a bit more appended to the end.

Notice also that the "msg" parameter in each function is decorated with the [ActivityTrigger] attribute, which is what makes each of these an Activity Function.

The Task.Delay() simulates a long-running activity. Imagine an activity that requires human input, such as a manager navigating to a web page and filling out a form. It might take days or weeks for this to happen. We certainly would not the application to continue running during this time: This would be an inefficient use of resources and it would be expensive. Durable functions handle this by storing state information in Azure storage; then retrieving that state when the function needs to resume.

Return to the DurableFunction1 class and replace the code with the following:

    public static class DurableFunction1 
    { 
        [FunctionName("DurableFunction1")] 
        public static async Task<IActionResult> Run( 
            [OrchestrationTrigger] DurableOrchestrationContext ctx, 
            ILogger log) 
        { 
            var msg = "Durable Function: "; 
             msg = await ctx.CallActivityAsync<string>("Function1", msg); 
            msg = await ctx.CallActivityAsync<string>("Function2", msg); 
            msg = await ctx.CallActivityAsync<string>("Function3", msg);

            // Use LogWarning, so it shows up in Yellow, making it easier to spot 
            log.LogWarning(msg);

            return new OkObjectResult(msg); 
        } 
    }
  

Listing 4

You will probably have to add the following to the top of the file in order for it to compile:

using Microsoft.AspNetCore.Mvc;

In Listing 4, we see that the Durable Function calls the 3 Activity functions in order. It passes to each Activity Function the output of the previous function. At then end of the orchestration, we expect to see a concatenation of messages from each of the 3 Activity Functions.

Notice also the parameter of type DurableOrchestrationContext, which is decorated with the [OrchestrationTrigger] attribute. This identifies this as a Durable Orchestration Function.

Finally, return to the StarterFunction class and replace the code with the following:

    public static class StarterFunction
    {
        [FunctionName("StarterFunction")]
        public static async Task<HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
            HttpRequestMessage req,
            [OrchestrationClient] DurableOrchestrationClient starter,
            ILogger log)
        {
            log.LogInformation("About to start orchestration");

            var orchestrationId = await starter.StartNewAsync("DurableFunction1", log);
            return starter.CreateCheckStatusResponse(req, orchestrationId);
        }
    }
  

Listing 5

To see this in action, compile and run the project. A console will display similar to the one in Fig. 8.

DF08-RunFunction
Fig. 8.

You can trigger the StarterFunction by issuing an HTTP GET to the URL displayed in the console (in this case http://localhost:7071/api/StarterFunction). Open a browser, enter this URL into the address bar, and press [ENTER].

Watch the console. You should see the log statements in each of the functions display in turn. Finally, we will see the final value of the msg variable after being passed to all 3 Activity functions. The output should look something like fig. 9.

DF09-FunctionComplete
Fig. 9

This illustrates the concepts of a Durable Orchestration Function. You can view the source code in the SequentialDurableFunctionDemo project at my Azure-Function-Demos GitHub repository.

Friday, 23 November 2018 09:23:00 (GMT Standard Time, UTC+00:00)
# Wednesday, 21 November 2018

Azure Functions allow you to declaratively add bindings to external resources by decorating a C# function with binding attributes.

This means you need to write less code and the code you do write will focus more on your business logic than on updating resources.

In this article, I will show you how to add CosmosDB bindings to an Azure function in order to read from and write to a CosmosDB database.

Create an Configure CosmosDB database and collection

See this article to learn how to create a new CosmosDB instance.

Next create a Database and Collection within your CosmosDB. This article describes how to create a CosmosDB Database and Collection; or you can quickly create a Database named "ToDoList" and a Collection named "Items" from the "Quick Start" tab of the CosmosDB database you created, as shown in Fig. 1.

CD01-QuickStart
Fig. 1

As you work with data in this database, you can view the documents on the "Data Explorer" tab, as shown in Fig. 2.

CD02-DataExplorer
Fig. 2

You will need the Connection String of your CosmosDB. You can find two connection strings on the "Keys" tab, as shown in Fig. 3. Copy either one and save it for later.

CD03-Keys
Fig. 3

Visual Studio project

Create a function in Visual Studio 2017. If you base it on the "Azure Functions" template (Fig. 4), it will have many of the necessary references.

CD04-NewAzureFunctionApp
Fig. 4

Open the local.settings.json file and add a key for "CosmosDBConnection", as shown in Fig. 5. Set its value to the connection string you copied from the "Keys" blade above.

CD05-localsettingsjson
Fig. 5

Delete the existing Function1.cs file from the project and add a new function by right-clicking the project in the Solution Explorer and selecting Add | New Function from the context menu, as shown in Fig. 6. Give the function a meaningful name.

CD06-AddFunction
Fig. 6

Repeat this for any function you wish to add.

Create a model of the expected data

CosmosDB is a schemaless document database, meaning that the database engine does not enforce the type of data it accepts. This is distinct from something like SQL Server, which requires you to define in advance the name, data type, and rules of each column you expect to store.

If you want to validate data, you must do so in your application. One way to do this is to create a Model class that matches the expected incoming data.

In my demo, I expect only to store data that looks like the following:

{
"id" : "001",
"description" : "Write blog post",
"isComplete" : false
}
  

So I created the ToDoItem class shown in Listing 1

public class ToDoItem 
 { 
    [JsonProperty("id")] 
    public string Id { get; set; }

    [JsonProperty("description")] 
    public string Description { get; set; }

    [JsonProperty("isComplete")] 
    public bool IsComplete { get; set; } 
 }
  

Listing 1

Insert a document

The code below generates a function to insert a new document into a database. The function is triggered when you send an HTTP POST request to the function's URL (in this case, "api/InserToDoItem). The document will have the value of the JSON

[FunctionName("InsertItem")] 
public static HttpResponseMessage Run( 
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]HttpRequestMessage req, 
    [CosmosDB( 
        databaseName: "ToDoList", 
        collectionName: "Items", 
        ConnectionStringSetting = "CosmosDBConnection")] 
    out ToDoItem document, 
    ILogger log) 
{ 
    var content = req.Content; 
    string jsonContent = content.ReadAsStringAsync().Result; 
    document = JsonConvert.DeserializeObject<ToDoItem>(jsonContent);

    log.LogInformation($"C# Queue trigger function inserted one row");

    return new HttpResponseMessage(HttpStatusCode.Created); 
}
  

Let's walk through the function.

[FunctionName("InsertItem")]

The name of the function is InsertItem

public static HttpResponseMessage Run(

The Run method executes when the function is triggered. It returns an HTTP Response Message

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]HttpRequestMessage req,

The first parameter is the incoming HTTP Request. It is decorated with HttpTrigger, indicating this is an HTTP trigger. Within this decorator's parameters, we indicate that the function can be called anonymously, that it can only be called with an HTTP POST (not GET or PUT or any other verb); and that we are not changing the default routing.

[CosmosDB(
      databaseName: "ToDoList",
      collectionName: "Items",
      ConnectionStringSetting = "CosmosDBConnection")]
     out ToDoItem document,        

The second parameter is an output parameter of type ToDoItem. We will populate this with the data in the Request body, so we type it as a ToDoItem. This parameter is decorated with the CosmosDB attribute, indicating that we will automatically insert this document into the CosmosDB. The databaseName, collectionName, and ConnectionStringSetting tell the function exactly where to store the document. The ConnectionStringSetting argument must match the name  we added     for the connection string in the local.settings.json file, as described above.

ILogger log)

The logger allows us to log information at points in the function, which can be helpful when troubleshooting and debugging.

var content = req.Content;
string jsonContent = content.ReadAsStringAsync().Result;
document = JsonConvert.DeserializeObject<ToDoItem>(jsonContent);

The 3 lines above retrieve the body in the HTTP POST request and convert it to a .NET object of type ToDoItem, which validates that it is the correct format.

log.LogInformation($"C# Queue trigger function inserted one row");

This line is not necessary, but may help us to understand what part of the function executed when we are troubleshooting.

return new HttpResponseMessage(HttpStatusCode.Created);

When the document is successfully inserted, we return an HTTP 201 (Created) status to indicate success.

Retrieve all documents

The following function retrieves all the documents in a container.

    public static class GetItems
    {
        [FunctionName("GetItems")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            [CosmosDB(
                databaseName: "ToDoList",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection",
                SqlQuery = "select * from Items")
            ]IEnumerable<ToDoItem> toDoItems,
            ILogger log)
        {
            log.LogInformation($"Function triggered");

            if (toDoItems == null)
            {
                log.LogInformation($"No Todo items found");
            }
            else
            {
                var ltodoitems = (List<ToDoItem>)toDoItems;
                if (ltodoitems.Count == 0)
                {
                    log.LogInformation($"No Todo items found");
                }
                else
                {
                    log.LogInformation($"{ltodoitems.Count} Todo items found");
                }
            }

            return new OkObjectResult(toDoItems);
        }
    }
  

Breaking down this function:

[FunctionName("GetItems")]        

The name of the function is “GetItems”.

public static async Task<IActionResult> Run(

The Run method executes when the function is triggered. This method is asynchronous and will eventually return an ActionResult.

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]HttpRequestMessage req,

The first parameter is the incoming HTTP Request. It is decorated with HttpTrigger, indicating this is an HTTP trigger. Within this decorator's parameters, we indicate that the function can be called anonymously, that it can only be called with an HTTP GET; and that we are not changing the default routing.

[CosmosDB(
databaseName: "ToDoList",
collectionName: "Items",
ConnectionStringSetting = "CosmosDBConnection",
SqlQuery = "select * from Items") ]IEnumerable<ToDoItem> toDoItems,

This parameter is what will be returned by the function (eventually, because it runs asynchronously). It is a list of objects of type ToDoItem. When serialized, this will be transformed into an array of JSON objects. This parameter is decorated with the CosmosDB attribute, indicating that we will automatically retrieve the list from the CosmosDB. The databaseName, collectionName, and ConnectionStringSetting tell the function exactly where to store the document. The SQlQuery tells what query to run to retrieve the data (in this case, return all the rows)

ILogger log)

The logger allows us to log information at points in the function, which can be helpful when troubleshooting and debugging.

log.LogInformation($"Function triggered");
if (toDoItems == null)
    {
         log.LogInformation($"No Todo items found");
    }
    else
    {
         var ltodoitems = (List<ToDoItem>)toDoItems;
         if (ltodoitems.Count == 0)
        {
            log.LogInformation($"No Todo items found");
        }
        else
        {
             log.LogInformation($"{ltodoitems.Count} Todo items found");
         }
    }

We did not need to write code to query the database. This happens automatically. The code above simply verifies that items were returned and transforms them into  List<ToDoItem> and stores this list in a local variable.

return new OkObjectResult(toDoItems);

We return a 200 (“OK”) HTTP response and the list of items.

Retrieve a single document by its ID

The following function retrieves a single document, given the ID.

    public static class GetItemById
    {
        [FunctionName("GetItemById")]
            public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "GetItem/{id}")] HttpRequestMessage req,
            [CosmosDB(
                databaseName: "ToDoList",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection",
                Id = "{id}")
            ]ToDoItem toDoItem,
            ILogger log)
        {
            log.LogInformation($"Function triggered");

            if (toDoItem == null)
            {
                log.LogInformation($"Item not found");
                return new NotFoundObjectResult("Id not found in collection");
            }
            else
            {
                log.LogInformation($"Found ToDo item {toDoItem.Description}");
                return new OkObjectResult(toDoItem);
            }

        }
    }
  

Here are the details of this function:

[FunctionName("GetItemById")]        

The name of the function is “GetItemById”

public static async Task<IActionResult> Run(

The Run method executes when the function is triggered. This method is asynchronous and will eventually return an ActionResult.

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]HttpRequestMessage req,

The first parameter is the incoming HTTP Request. It is decorated with HttpTrigger, indicating this is an HTTP trigger. Within this decorator's parameters, we indicate that the function can be called anonymously, that it can only be called with an HTTP GET; and that we are not changing the default routing.

[CosmosDB(
databaseName: "ToDoList",
collectionName: "Items",
ConnectionStringSetting = "CosmosDBConnection",
Id = "{id}")
]IEnumerable<ToDoItem> toDoItems,
 

This parameter is what will be returned by the function (eventually, because it runs asynchronously). It will be an object of type ToDoItem. This parameter is decorated with the CosmosDB attribute, indicating that we will automatically retrieve the list from the CosmosDB. The databaseName, collectionName, and ConnectionStringSetting tell the function exactly where to store the document. The id tells the function on which Id to filter the results.  

ILogger log)

The logger allows us to log information at points in the function, which can be helpful when troubleshooting and debugging.

log.LogInformation($"Function triggered");

Debugging information. Not necessary for the operation, but helpful when troubleshooting.  

if (toDoItem == null)
{
    log.LogInformation($"Item not found");
   return new NotFoundObjectResult("Id not found in collection");
}
else
{
    log.LogInformation($"Found ToDo item {toDoItem.Description}");
   return new OkObjectResult(toDoItem);
}

We did not need to write code to query the database. This happens automatically. The code above simply checks if an item was returned matching the ID. If an item is found, we return a 200 (“OK”) HTTP response, along with the item. If no item is returned, we return a 404 (“Not Found) HTTP response.


Retrieve a set of documents using a query

The following function retrieves a set of document. A query tells the function how to filter, sort and otherwise retrieve the documents. In this example, we only want to return documents for which isComplete = true.

    public static class GetCompleteItems
    {
        [FunctionName("GetCompleteItems")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
            [CosmosDB(
                databaseName: "ToDoList",
                collectionName: "Items",
                ConnectionStringSetting = "CosmosDBConnection",
                SqlQuery = "select * from Items i where i.isComplete")
            ]IEnumerable<ToDoItem> toDoItems,
            ILogger log)
        {
            log.LogInformation($"Function triggered");

            if (toDoItems == null)
            {
                log.LogInformation($"No complete Todo items found");
            }
            else
            {
                var ltodoitems = (List<ToDoItem>)toDoItems;
                if (ltodoitems.Count == 0)
                {
                    log.LogInformation($"No complete Todo items found");
                }
                else
                {
                    log.LogInformation($"{ltodoitems.Count} Todo items found");
                }
            }

            return new OkObjectResult(toDoItems);
        }
    }
  

We will now explore this function in more detail:   

[FunctionName("GetCompleteItems")]        

The name of the function is “GetCompleteItems”.

public static async Task<IActionResult> Run(

The Run method executes when the function is triggered. This method is asynchronous and will eventually return an ActionResult.

[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)]HttpRequestMessage req,

The first parameter is the incoming HTTP Request. It is decorated with HttpTrigger, indicating this is an HTTP trigger. Within this decorator's parameters, we indicate that the function can be called anonymously, that it can only be called with an HTTP GET; and that we are not changing the default routing.

[CosmosDB(
databaseName: "ToDoList",
collectionName: "Items",
ConnectionStringSetting = "CosmosDBConnection",
SqlQuery = "select * from Items i where i.isComplete")
]IEnumerable<ToDoItem> toDoItems,

This parameter is what will be returned by the function (eventually, because it runs asynchronously). It is a list of objects of type ToDoItem. When serialized, this will be transformed into an array of JSON objects. This parameter is decorated with the CosmosDB attribute, indicating that we will automatically retrieve the list from the CosmosDB. The databaseName, collectionName, and ConnectionStringSetting tell the function exactly where to store the document. The SQlQuery tells what query to run to retrieve the data (in this case, return only rows with isComplete=true) It is important to note that I am using the JSON property (“isComplete”), rather than the .NET class property (“IsComplete”) in this query. Even though they differ only in their case, the query is case-sensitive.  

ILogger log)

The logger allows us to log information at points in the function, which can be helpful when troubleshooting and debugging.

log.LogInformation($"Function triggered");
if (toDoItems == null)
    {
         log.LogInformation($"No complete Todo items found");
    }
    else
    {
         var ltodoitems = (List<ToDoItem>)toDoItems;
         if (ltodoitems.Count == 0)
        {
            log.LogInformation($"No complete Todo items found");
        }
        else
        {
             log.LogInformation($"{ltodoitems.Count} Todo items found");
         }
    }

We did not need to write code to query the database. This happens automatically. The code above simply verifies that items were returned and transforms them into  List<ToDoItem> and stores this list in a local variable.

return new OkObjectResult(toDoItems);

We return a 200 (“OK”) HTTP response and the list of items.

Conclusion

Notice that in each of these functions, I did not need to write code to query or update the database. By decorating a parameter with the CosmosDb attribute, the function automatically took care of the database operations.

You can find this code in the CosmosDBBinding solution in my Azure Function demos on GitHub.

Wednesday, 21 November 2018 09:07:00 (GMT Standard Time, UTC+00:00)
# Tuesday, 20 November 2018

In previous articles, I showed how to create Azure Function Apps and Azure Functions directly in the Azure Portal. You can also create Function Apps and Functions in Visual Studio and then deploy them to Azure. I prefer to do this, because it makes it easier to get my code into source control.

Before working with and creating Azure artifacts in Visual Studio, you must install the Azure tools. To install these tools, launch Visual Studio installer and check "Azure Development, as shown in Fig. 1.

AF01-AzureDevTools
Fig. 1

Once the Azure tools are installed, launch Visual Studio and select File | New | Project  from the menu, as shown in Fig. 2.

AF02-FileNewProject
Fig. 2

In the "New Project" dialog, expand Visual C# | Cloud in the left tree and select "Azure Functions" from the list of templates; then enter a project name and location, as shown in Fig. 3.

AF03-AzureFunctionTemplate
Fig. 3

The next dialog (Fig. 4) presents a list of options for your Azure Function.

AF04-FunctionOptions
Fig. 4

In the top dropdown, select "Azure Functions v2".

Select "Http Trigger" to create a function that will be triggered by an HTTP GET or POST to a web service URL.

At the "Storage Account" dropdown, select "Storage Emulator". This works well for running and testing your function locally. You can change this to an Azure Storage Account when you deploy the Function to Azure.

At the "Access rights" dropdown, select "Function".

Click the [OK] button to create an Azure Function App with a single Azure Function.

A function is generated with the following code:

[FunctionName("Function1")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    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;

    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
  

Listing 1

The method is decorated with the "FunctionName" attribute, which provides the name of the function.

[FunctionName("Function1")]
  

Notice that the first parameter is decorated with

[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
  

This tells the system that the Function is triggered by an HTTP request and that it will request either a GET or POST verb.

We also pass in an ILogger, so that we can output debugging information.

Let's walk through the code in this function

Log some information, so we can confirm the function was properly triggered.

log.LogInformation("C# HTTP trigger function processed a request.");
  

If a "name" parameter is passed in the querystring, capture the value of this parameter.

string name = req.Query["name"];
  

If this is a POST request, there may be information sent in the request body. Retrieve this information and convert it to a JSON object:

string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); 
dynamic data = JsonConvert.DeserializeObject(requestBody);
  

If the "name" parameter was passed in the querystring, use that; if not, look for it in the JSON object from the request body.

name = name ?? data?.name;
  

If a "name" parameter was found, return an HTTP Response Code 200 (OK) with a body containing the text "Hello, " followed by the value of the name.

If no "name" parameter was passed, return an HTTP Response Code 400 (Bad Request) with a message into the body indicating a name is required.

return name != null 
    ? (ActionResult)new OkObjectResult($"Hello, {name}") 
    : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
  

Publish App

One quick way to publish a Function App to Azure is directly from Visual Studio. To do this, right-click the project in the Solution Explorer and select "Publish" from the context menu, as shown in Fig. 5.

AF05-RightClickPublish
Fig. 5

The "Pick a publish target" dialog displays, as shown in Fig. 6.

AF06-PickPublishTarget
Fig. 6

Check the "Run from ZIP" checkbox.

Select either the "Create New" or "Select Existing" radio button, depending whether you wish to deploy to an existing or a newly-created Azure Function; then click the [Publish] button.

The follow-up dialog if you select "Create New" is shown in Fig. 7a and for "Select existing" in Fig. 7b.

Click the [OK] or [Create] button at the bottom of the follow-up dialog to deploy the Function.

This article showed how to create an Azure Function App in Visual Studio, making it easier to test locally and integrate your code with source control.

Tuesday, 20 November 2018 09:41:00 (GMT Standard Time, UTC+00:00)
# Friday, 16 November 2018

In a previous article, I showed you how to create a new Azure Function with an HTTP trigger.

After you create an Azure Function, it is useful to be able to test it right in the Azure Portal.

To test an Azure function, log into the Azure Portal, open the Function App, and select your Function, as shown in Fig. 1

TF01-Function
Fig. 1

Click the [Run] button (Fig. 2) above the Function to open a Log output window and a Testing dialog, as shown in in Fig. 3.

TF02-RunButton
Fig. 2

TF03-TestDialog
Fig. 3

In the Test dialog on the right, you can change the HTTP verb by selecting either "POST" or "GET" in the "HTTP method" dropdown, as shown in Fig. 4.

TF04-HttpMethod
Fig. 4

If you select the "POST" HTTP method, the "Request body" section (Fig. 5) is enabled and you can modify the data you want to send in the HTTP Body of your request.

TF05-RequestBody
Fig. 5

You can add querystring parameters to your request by clicking the "+ Add parameter" link under "Query" (Fig. 6) and entering a name and value of the parameter, as shown in Fig. 7.

TF06-QueryParameters
Fig. 6

TF07-AddParameter
Fig. 7

Repeat this for as many querystring parameters as you need.

Similarly, you can add name/value pairs to the HTTP header of your  request by clicking the "+ Add header" link and entering the name and value of each header, as shown in Fig. 8.

TF08-AddHeader
Fig. 8

When everything is configured the way you want, click the [Run] button at the bottom (Fig.9) to call the web service and trigger your function.

TF09-RunButton
Fig. 9

The "Output" section (Fig. 10) will display the HTTP response, as well as any text returned in the body of the response. Any response between 200 and 299 is good; any response of 400 and above indicates an error.

TF10-Output
Fig. 10

If you function outputs log information, you will see this in the Log output window, as shown in Fig. 11.

TF11-LogOutput
Fig. 11

In this article, I showed how to test a function from within the Azure portal. You should create more sophisticated automated test as part of your build/deploy process, but this serves as a good, simple way to make sure your function is behaving as expected after you create it.

Friday, 16 November 2018 19:06:00 (GMT Standard Time, UTC+00:00)
# Thursday, 15 November 2018

GCast 22:

Creating an Azure Function Proxy

Learn how to create a proxy URL using Azure Functions

Thursday, 15 November 2018 09:49:00 (GMT Standard Time, UTC+00:00)
# Wednesday, 14 November 2018

In the last article, I showed how to create an Azure Function App. A Function App is not useful by itself: it is just a container for functions, which perform the real work.

Once you have created an Azure Function App, you will want to add one or more Functions to it.

Navigate to the Azure Portal, log in, and open your Function app, as shown in Fig. 1.

Fu01-FunctionApp
Fig. 1

Click either the [+] icon next to the "Functions" section on the left (Fig. 2) or the [New function] button at the bottom (Fig. 3)

Fu02-NewFunctionIcon
Fig. 2

Fu03-NewFunctionButton
Fig. 3

NOTE: If this Function App already contains at least one function, the [New function] button does not display.

The "CHOOSE A DEVELOPMENT ENVIRONMENT" page of the "Azure Functions for .NET - getting started" dialog displays, as shown in Fig. 4

Fu04-ChooseDevEnv
Fig. 4

Select the [In-portal] tile and click the [Continue] button to advance to the "CREATE A FUNCTION" page, as shown in Fig. 5

Fu05-CreateAFunction
Fig. 5

Two triggers are listed: "Webhook+API", which will cause your function to execute after a web service URL is hit; and "Timer", which allows you to schedule your function to run at regular intervals. You can see more triggers by clicking the "More templates…" tile; but, for this demo, select the [Webhook+API] tile and click the [Create] button. After a few seconds, a function is created with an HTTP trigger and some sample code, as shown in Fig. 6.

Fu06-NewFunction
Fig. 6

This sample function accepts a "name" parameter (either in the querystring or in the Body of a POST request) and returns an HTTP 200 (OK) response with the string "Hello, ", followed by the value of the name parameter. If no "name" parameter is supplied,  it returns a 400 (Bad Request) response with an error message.

You can now modify and save this code as you like.

In the next article, I will show you how to test this function within the portal.

Wednesday, 14 November 2018 09:59:00 (GMT Standard Time, UTC+00:00)
# Tuesday, 13 November 2018

An Azure Function allows you to deploy scalable code to the cloud without worrying about the server or other infrastructure issues.

Azure Functions are contained within a Function App, so you need to create a Function App first.  To create a Function App, navigate to the Azure Portal, sign in and click the [Create a resource] button, as shown in Fig. 1.

FA01-CreateAResource
Fig. 1

From the menu, select Compute | Function App, as shown in Fig. 2.

FA02-ComputeFunctionApp
Fig. 2

The "Create Function App" blade displays as shown in Fig. 3

FA03-CreateFunctionAppBlade
Fig. 3

At the "App Name" field, enter a unique name for your Function App.

At the "Subscription" field, select the Azure subscription with which to associate this Function App. Most people will have only one subscription.

At the "Resource Group" field, select "Create new" and enter the name of a Resource Group to create or select "Use existing" and select an existing resource group in which to store your Function App. A Resource Group is an organizational grouping of related assets in Azure.

At the "OS" radio button, select the operating system (Windows or Linux) on which you wish to host your Function App.

At the Hosting plan, select either "Consumption Plan" or "App Service Plan". With the Consumption Plan, you only pay for the time that your functions are running. Since most functions do not run 24 hours a day / 7 days a week, this can be a real cost savings. With the App Service Plan, you pay as long as your functions are available. This is appropriate if you expect clients to be constantly calling your functions.

At the "Location" field, enter a region in which you want your Functions to run. In order to minimize latency, you should select a region close to any resources with which the Functions will interact.

At the "Runtime Stack" dropdown, select one of the platforms. Select ".NET" if you plan to write your code in C# or F#. Select "JavaScript" if you plan to create a node function. Select "Java" if you plan to write your code in Java. As of this writing, Java is in Preview, so performance is not guaranteed.

If you selected "Consumption Plan" hosting plan, you will be prompted for a storage account. Function definitions will be stored in this account. Select an existing storage account or create a new one. I prefer to use a storage account for all my Function Apps in a given Resource Group.

For extra monitoring, turn on Application Insights and select the same region in which your Function App is located. If this region is not available, select a nearby region.

Click the [Create] button to create your Function App.

After your Function App is created, you will want to add a Function to it. I will show how to do this in the next article.

Tuesday, 13 November 2018 09:54:00 (GMT Standard Time, UTC+00:00)
# Friday, 09 November 2018

Azure Functions provide a simple way to deploy code in a scalable, cost-effective way.

The beauty of Azure functions is that the developer does not need to worry about where they are deployed. Azure takes care of spinning up a server and other resources at the appropriate time and scaling out a Function as demand increases. The infrastructure is abstracted away from the developer allowing the developer to focus on the code and the business problem.

Azure functions can be written in C#, F#, JavaScript, or Java.

Each Function has a "Trigger" which, as the name implies is an event that causes the function code to run. This can be an HTTP request, a message on a queue or message bus, delivery of an email, data inserted into a blob storage container or CosmosDB database, or a timed interval.

Triggers are just one way that Azure functions can easily connect to other services. There are also bindings available to interact with databases, queues, and other services with a minimum of code.

One nice feature of Azure Function Apps is the "Consumption Plan" pricing model. Selecting this plan means that you are only charged while your function is running, which can save plenty of money - particularly if your app is not running 24 hours a day every day. Of course, you can also choose to run your function as part of an App Service Plan, in which case you will pay for the entire time the function is available, whether or not it is running. This may be desirable if you already have an App Service Plan running and want to include your functions in that same plan.

You can create functions directly in the Azure Portal. Or you can create them locally using tools like Visual Studio and Visual Code and deploy them either directly from the IDE or through your continuous integration processes.

The source code for the Azure Functions run-time is even open source! Check out the code at https://github.com/Azure/azure-functions-host.

You can get a free Azure account at http://azure.com. You can read more about Azure functions at https://docs.microsoft.com/en-us/azure/azure-functions.

In upcoming articles, I'll show you how to create, deploy, test, and manage Azure functions.

Friday, 09 November 2018 09:25:00 (GMT Standard Time, UTC+00:00)
# Thursday, 08 November 2018

GCast 21:

Azure Functions Continuous Deployment

Learn how to configure continuous deployment from GitHub to Azure functions. Each time you push code changes to GitHub, that code is automatically deployed to Azure.

Thursday, 08 November 2018 09:48:00 (GMT Standard Time, UTC+00:00)
# Thursday, 01 November 2018
Thursday, 01 November 2018 09:02:00 (GMT Standard Time, UTC+00:00)
# Monday, 29 October 2018

Episode 535

Rajasa Savant on Serverless Azure

Microsoft Engineer Rajasa Savant describes the "Serverless" technologies available in Microsoft Azure

Monday, 29 October 2018 08:56:00 (GMT Standard Time, UTC+00:00)
# Thursday, 25 October 2018
Thursday, 25 October 2018 09:37:00 (GMT Daylight Time, UTC+01:00)