# Thursday, 06 December 2018

GCast 25:

Azure Durable Functions

By default, Azure Durable Functions are stateless. But durable functions allow you to maintain state across multiple, long-running functions.

Thursday, 06 December 2018 09:20:00 (GMT Standard Time, UTC+00:00)
# Wednesday, 05 December 2018

In previous articles, I showed how to create an application using the Microsoft Bot Framework using Visual Studio. But you can also create a chatbot application directly within the browser.

Navigate to the Azure Portal and log in.

Click the [Create a resource] button (Fig. 1) and select AI + Machine Learning | Web App Bot, as shown in Fig. 2.

BB01-CreateButton
Fig. 1

BB02-Menu
Fig. 2

The "Web App Bot" blade displays, as shown in Fig. 3.

BB03-NewBotBlade
Fig. 3

At the "Bot name" field, enter a unique name for your bot.

At the "Subscription" field, select the Azure subscription with which to associate this bot.

At the "Resource group" field, select an existing resource group to contain your bot or click the "Create new" link to create a new resource group.

At the "Location" field, select a region in which your bot should be located. Consider the location of any resources it will be consuming and users that will communicate with it.

At the "Pricing tier", select "F0" for a free bot or "S1" for a paid bot with fewer limitations.

At the "App name" field, enter a unique name for the web service exposed by your bot.

At the "Bot template" field, select either "Basic Bot" for a simple example of a bot using LUIS, Analytics, and Storage or "Echo Bot" for an even simpler bot.

If you select "Basic Bot" template, you will need to select the location of the LUIS service. Only a few regions currently support LUIS; but you should try to keep it close to your bot location.

At the "App service plan" field, select or create a new App Service plan. This defines the location and location of the servers on which your code will run. At creation, only S1 servers are available, but you can change this after the bot is created.

At the "Azure Storage" field, select or create an Azure Storage account in which to save bot configuration and state information.

If desired, turn on application insights and select a location for this service.

An App ID and password are required for a Microsoft Bot. By default, these values are automatically generated for your. If desired, you may explicitly set these values. 

A completed blade is shown in Fig. 4.

BB04-NewBotBlade
Fig. 4

After a few minutes, a notification indicates the bot is created. Click the [Go to resource] button (Fig. 5) or use the left menu to search for the bot by name.

BB05-GoToResource
Fig. 5

By default, the bot's "Overview" blade displays, as shown in Fig. 6.

BB06-BotOverview
Fig. 6

To test your bot, click the "Test in Web Chat" blade and type "Hello" in the textbox labeled "Type your message here" to begin a conversation. A sample conversation for the Basic Bot is shown in Fig 7.

BB07-TestBot
Fig. 7

From the "Build" blade (Fig. 8), you can click the "Open online code editor" to edit your code directly in the browser; or click the [Download bot source code] to generate and download a ZIP file of a C# solution containing your code.

BB08-BuildBlade

In this article, I showed how to build a bot app in the portal in your browser.


Fig. 8

Wednesday, 05 December 2018 07:52:30 (GMT Standard Time, UTC+00:00)
# Tuesday, 04 December 2018

Joey DeFrancesco TrioJazz musicians are famous for playing the notes around the melody, adding their own interpretation of a tune. But the tremolo of Joey DeFrancesco's organ does much of that for him.

the Joey DeFrancesco Trio brought played a delightful set Sunday night at the Jazz Showcase in Chicago's South Loop. Most songs began with a mellow feel, then increased in energy until each was swinging and/or rocking.

Like most great band leaders, DeFrancesco knows to find and showcase great musicians. In this trio, it was saxophonist Victor North, whose solos captivated the audience. Drummer Khary Shahee was solid throughout and seemed determined to play every solo with his eyes closed.

David and JoeyThe Trio played a mix of originals ("Blues in Three", "Trip Mode") and arrangements of other composers tunes, including an extended version of Cole Porter's classic "Night and Day".  One highlight was the beautiful melody of "Easy to Remember" and the final song of the night – an up-tempo, frenzied piece in which each member of the band tried to outperform one another in turn.

It wasn't a long set - maybe 75 minutes - and the second set was canceled due to low ticket sales; but those who came out saw an excellent performance.

Tuesday, 04 December 2018 09:28:00 (GMT Standard Time, UTC+00:00)
# Monday, 03 December 2018

Episode 540

Bill Wagner on Nullable Reference Types

C# 8 will have support for Nullable reference types, which will allow you to know better when you need to check for null in your variables. Bill explains the syntax and implication of this upcoming language feature.

Monday, 03 December 2018 09:04:00 (GMT Standard Time, UTC+00:00)
# Sunday, 02 December 2018

12/2
Today I am grateful to pay off some sleep debt the past few days.

12/1
Today I am grateful for a warm day in December.

11/30
Today I am grateful that I live 1 block from a grocery store.

11/29
Today I am grateful for floor seats to see an exciting DePaul - CSU basketball game last night on my first visit to WinTrust Arena.

11/28
Today I am grateful that the severe back pain that began earlier this month is almost entirely gone.

11/27
Today I am grateful for a hot bath on a cold evening.

11/26
Today I am grateful that my toilet is finally fixed.

11/25
Today I m grateful to stay home and watch college football on a Saturday.

11/24
Today I am grateful for. a slow drive across Michigan with frequent stops yesterday.

11/23
Today I am grateful to spend Thanksgiving with my family.

11/22
Today I am grateful for my first visit to the UK.

11/21
Today I am grateful
-for a guided walking tour of historic London yesterday morning
-for a visit to the UK National Gallery yesterday afternoon
-to my new manager for traveling to London to meet me for dinner last night

11/20
Today I am grateful for lunch with Andy yesterday.

11/19
Today I am grateful to meet up with 2 old friends in a foreign country: James at lunch; and Tobiasz at dinner.

11/18
Today I am grateful to speak at #GangConf in Detroit yesterday.

11/17
Today I am grateful for:
-Lunch with Suzanne and Darcy yesterday
-Ondrej and Desi letting me stay at their home last night

11/16
Today I am grateful for my first acupuncture session yesterday.

11/15
Today I am grateful for all 4 seasons.

11/14
Today I am grateful for Taco Tuesday at Flaco's.

11/13
Today I am grateful for an independent press.

11/12
Today I am grateful for a day in Milwaukee with friends.

11/11
Today I am grateful for my first-ever visit to a chiropractor yesterday.

11/10
Today I am grateful to work from on the first very cold day of the season.

11/9
Today I am grateful for the opportunity to mentor startups and entrepreneurs at The University of Chicago Polsky Exchange the past 4 years.

11/8
Today I am grateful to see The Jeff Lorber Fusion in concert last night at The Promontory.

11/7
Today I am grateful for the opportunity to vote yesterday.

11/6
Today I am grateful for a tour yesterday of Epic Systems, one of the most creatively-designed campuses I've seen.

Sunday, 02 December 2018 18:38:13 (GMT Standard Time, UTC+00:00)
# Saturday, 01 December 2018

BridesheadRevisitedIn his first year at University, Charles Ryder meets Sebastian Flyte and is immediately attracted to him. Sebastian is handsome, rich, charming, and carefree and the two of them quickly become inseparable, drinking together at every opportunity.

Sebastian invites Charles home to Brideshead Castle. Sebastian describes the palatial estate as "It's where my family lives". Despite the barriers Sebastian erects between himself and his family, the Flytes almost immediately accept Charles as one of their own.

The family is an interesting mix of characters - the beautiful and intelligent Julia, who looks and sounds much like Sebastian; the idealistic Cordelia; the strong and pious mother Lady Marchmain; and the father Lord Marchmain, who abandoned his family to live with his mistress in Venice. Sebastian spends much of his time at home drinking to excess, despite his family's efforts to prevent him from doing so.

Eventually, Sebastian's drinking becomes so severe that his family has no idea how to help him; and he leaves home, largely exiting the story except in secondhand reports.

But Charles and the Flytes remain and Brideshead Revisited by Evelyn Waugh is their story.

The Flytes are very wealthy and part of the upper social strata of English aristocracy. But they are also Roman Catholic, which is a rarity in Anglican England and which affects both how they view the world.

The story follows Charles through 3 phases of his life - framed by a wartime visit to an abandoned Brideshead, which sparks his memories of his life with the Flytes.

In Part 1 ("Et In Arcadia Ego"), Charles and Sebastian meet and form a very close relationship. Some critics have described this as a homosexual relationship. I'm inclined to believe it is not because Waugh never mentions anything physical between the two and he does explicitly introduce other homosexuals into the narrative. Regardless, Sebastian and Charles become close enough that they end up spending all their free time together and eventually stop seeing their other friends - a pattern into which romantic couples often fall. There is no question of the love they feel for one another. It is in this part that Charles begins to bond with the Flyte family.

In Part 2 ("Brideshead Deserted"), the characters drift apart. Sebastian is an alcoholic and has left the family and traveled to Africa. Charles marries and becomes a successful painter. The other Flytes go out in the world, seeking careers and love. It concludes with Charles reconnecting with and falling in love with Sebastian's married sister Julia. Each agrees to divorce their spouse to be free to marry one another.

In Part 3 ("A Twitch Upon the Thread"), most of the family returns to Brideshead, including the dying Lord Marchmain and deal with their changing lives. The Catholicism of the Flyte family takes center stage in this section, particularly when contrasted with the agnostic Charles and Lord Marchmain.

Brideshead is about the English idle rich between the world wars; about the British caste system; about the decline of the aristocracy; about personal responsibility; about religion and its influence on moral choices; about sexuality; and about love and friendship.

Charles is an outsider in the aristocratic world of the Flytes; but he is not a dispassionate observer. He injects himself fully into the family and they embrace him. Some even love him. But the family is filled with drama and conflict. And Charles becomes part of it.

Most of the characters deteriorate as the novel progresses. Even Brideshead Manor itself falls into disrepair as the family abandons it to pursue interests elsewhere. In the beginning, most characters possess the optimism of youth; but, by Part 3, they have either aged poorly, become disillusioned, or squandered their lives as a wandering alcoholic. Still, there is optimism in this novel. And some are at least partially saved by an epiphany and a religious conversion late in life.

Brideshead Revisited is a complex story that reminds us that life is a journey that takes us both forward and backward and that we have control over where it takes us. It is a personal story told by Charles and his recollections force him at last to reconsider his life.

Saturday, 01 December 2018 09:52:00 (GMT Standard Time, UTC+00:00)
# 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)