<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>benjamin perkins</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/benjaminperkins/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/feed.xml</link>
    <description>List&amp;lt;Solution&amp;gt; solutions = changes.Where(c =&amp;gt; c.CeterisParibus != true)</description>
    <lastBuildDate>Mon, 29 Apr 2019 13:52:56 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Azure Functions - Timer</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-timer</link>
      <pubDate>Fri, 02 Nov 2018 15:26:44 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=30505</guid>
      <description><![CDATA[This lab has been moved to its new home...]]></description>
      <content:encoded><![CDATA[This lab has been moved to its new home here: https://benperk.github.io/azure/training/azure-functions-timer.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with a Timer.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer" rel="noopener">here</a> “Timer trigger for Azure Functions” which discusses the Timer trigger in detail so I will not readdress that content.

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.

As you will see later, the default Run() method for a Timer Trigger contains a parameter of type TimerInfo as defined <a target="_blank" href="https://github.com/Azure/azure-webjobs-sdk-extensions/blob/master/src/WebJobs.Extensions/Extensions/Timers/TimerInfo.cs" rel="noopener">here</a> on GitHub.  Looking at the TimerInfo class code on GitHub you can see the different methods and accessible public properties.  In addition to that, later I will use <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection" rel="noopener">Reflection</a> to dump them out, just for some extra fun.

When you want an Azure Function to run at a certain time interval you can achieve that using a Timer trigger.   You might also consider using a WebJob, the underlying SDK is the same and if you already an App Service Plan (<a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2014/10/01/azure-website-hosting-plans-whp/" rel="noopener">*</a>) then you might save some money.  Here are some articles which I wrote about WebJobs:
<ul>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2016/09/01/how-to-setup-cron-to-run-a-webjob-on-the-azure-app-service-platform/" rel="noopener">How to setup CRON to run a WebJob on the Azure App Service platform</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2016/02/01/using-the-azure-webjob-api/" rel="noopener">Using the Azure WebJob API</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2015/06/01/helloworld-webjob-on-microsoft-azure-web-app/" rel="noopener">Helloworld WebJob on Microsoft Azure – Web App</a></li>
 	<li>All my WebJob articles <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/tag/webjob/" rel="noopener">here</a></li>
 	<li>A GitHub troubleshooting article, <a target="_blank" href="https://github.com/Azure/azure-functions-host/wiki/Investigating-and-reporting-issues-with-timer-triggered-functions-not-firing" rel="noopener">Investigating and reporting issues with timer triggered functions not firing</a></li>
</ul>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb72.png"><img width="855" height="337" title="image_thumb7" style="margin: 0px;border: 0px currentcolor" alt="image_thumb7" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb7_thumb1.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with an Timer trigger</span></strong>

Then find and select the Timer trigger template, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image68.png"><img width="496" height="262" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb67.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with an Timer trigger</span></strong>

Then provide the Name and the CRON Trigger sequence as seen in Figure 3.  <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer#cron-expressions" rel="noopener">Here</a> and <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer#cron-examples" rel="noopener">here</a> are some examples of CRON expressions.  In Figure 3, a C# function with the name of TimerTrigger will run every 2 minutes, or 30 times per hour, 720 times per day.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image69.png"><img width="489" height="400" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb68.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with an Timer trigger</span></strong>

Here is an example of the default Run() method.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:18794675-d206-4598-bcb1-e007673b705b" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
using System;

public static void Run(TimerInfo myTimer, ILogger log)
{
    log.LogInformation($&quot;C# Timer trigger function executed at: {DateTime.Now}&quot;);
}
[/sourcecode]

</div>
<h1>Lab 16</h1>
Just for fun, find out using reflection which properties and methods exist within the <strong>TimerInfo</strong> class, update the Azure Function so that it resembles the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:77697f71-0cf8-45f2-924e-945ff6e6f2df" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
using System;
using System.Reflection;

public static void Run(TimerInfo myTimer, ILogger log)
{
   log.LogInformation($&quot;C# Timer trigger function executed at: {DateTime.Now}&quot;);
   Type timerInfo = typeof(TimerInfo);
   log.LogInformation(&quot;TimerInfo Methods:&quot;);
   MethodInfo[] methodInfo = timerInfo.GetMethods();
   foreach (MethodInfo mInfo in methodInfo)
   {
      log.LogInformation($&quot;{mInfo.ToString()}&quot;);
   }
   log.LogInformation(&quot;TimerInfo Members:&quot;);
   MemberInfo[] memberInfo = timerInfo.GetMembers();
   foreach (MemberInfo mbInfo in memberInfo)
   {
      log.LogInformation($&quot;{mbInfo.ToString()}&quot;);
   }
   log.LogInformation($&quot;Is past due: {myTimer.IsPastDue.ToString()}&quot;);
   log.LogInformation($&quot;Schedule: {myTimer.Schedule.ToString()}&quot;);
   log.LogInformation($&quot;Schedule Status Last: {myTimer.ScheduleStatus.Last.ToString()}&quot;);
   log.LogInformation($&quot;Schedule Status Next: {myTimer.ScheduleStatus.Next.ToString()}&quot;);
   log.LogInformation($&quot;Schedule Status LastUpdated: {myTimer.ScheduleStatus.LastUpdated.ToString()}&quot;);
}
[/sourcecode]

</div>
The items to note here are:
<ol>
 	<li>I included the reference to System.Reflection.</li>
 	<li>I cast an instance of the TimerInfo class into the timerInfo object</li>
 	<li>Then I called the GetMethods() and GetMembers() methods and cycled through the results within a foreach statement</li>
</ol>
The output, when run from the portal looked something like the following, I would expect the same output when it is triggered.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b0633974-15e3-4190-b04c-d137779ece85" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
[Information] Executing 'Functions.TimerTrigger' (Reason='Timer fired at 2018-10-16T12:51:59', Id=...4aa)
2018-10-16T12:49:35.848 [Information] C# Timer trigger function executed at: 10/16/2018 12:49:35 PM
2018-10-16T12:49:35.848 [Information] TimerInfo Methods:....
2018-10-16T12:49:35.849 [Information] TimerInfo Members:...
2018-10-16T12:49:35.850 [Information] Boolean IsPastDue
2018-10-16T12:49:35.850 [Information] Is past due: False
2018-10-16T12:49:35.850 [Information] Schedule: Cron: '0,2,4,6,8,10,12,14,16,18,20,...,32,34,... * * * *'
2018-10-16T12:49:35.850 [Information] Schedule Status Last: 10/16/2018 12:48:00 PM
2018-10-16T12:49:35.850 [Information] Schedule Status Next: 10/16/2018 12:50:00 PM
2018-10-16T12:49:35.850 [Information] Schedule Status LastUpdated: 10/16/2018 12:48:00 PM
2018-10-16T12:49:35.851 [Information] Executed 'Functions.TimerTrigger' (Succeeded, Id=...4aa)
[/sourcecode]

</div>
You can also view the output via the Monitor blade for the given Function, as seen in Figure 4.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image70.png"><img width="855" height="234" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb69.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to monitor an Azure Function with a Timmer trigger</span></strong>

Again, <a target="_blank" href="https://github.com/Azure/azure-functions-host/wiki/Investigating-and-reporting-issues-with-timer-triggered-functions-not-firing" rel="noopener">here</a> are some interesting troubleshooting notes for a timer triggered function –&gt; “Investigating and reporting issues with timer triggered functions not firing”.
<h1>Lab 16.1</h1>
Before completing this lab make sure you have completed Lab 1, Lab 1.1, Lab 4 and Lab 4.1.  The blob trigger in Lab 1 inserted a blob and then in Lab 1.1 it is deleted.  In Lab 4, you have created an Event Hub trigger that processes a message.  In Lab 4.1, you create a blob using the CloudBlockBlob class to create a blob using the contents of the Event Hub message and stored it in a storage container.  In this lab you will update the Timer function to send a message to the Event Hub which will send the message (as a blob) to the blob storage which will dump the details and delete it.  Similar to that shown in Figure 5.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image71.png"><img width="855" height="316" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb70.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to monitor an Azure Function with a Timmer trigger</span></strong>

Update the Azure Function code so that it resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f75588bf-86f9-465e-8b46-ed546bfd66ad" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.Azure.EventHubs&quot;

using System;
using System.Reflection;
using System.Text;

using Microsoft.Azure.EventHubs;

private static EventHubClient eventHubClient;

public static void Run(TimerInfo myTimer, ILogger log)
{
    log.LogInformation($&quot;C# Timer trigger function executed at: {DateTime.Now}&quot;);
    Type timerInfo = typeof(TimerInfo);
    log.LogInformation(&quot;TimerInfo Methods:&quot;);
    MethodInfo[] methodInfo = timerInfo.GetMethods();
    foreach (MethodInfo mInfo in methodInfo)
    {
       log.LogInformation($&quot;{mInfo.ToString()}&quot;);
    }
    log.LogInformation(&quot;TimerInfo Members:&quot;);
    MemberInfo[] memberInfo = timerInfo.GetMembers();
    foreach (MemberInfo mbInfo in memberInfo)
    {
       log.LogInformation($&quot;{mbInfo.ToString()}&quot;);
    }
    log.LogInformation($&quot;Is past due: {myTimer.IsPastDue.ToString()}&quot;);
    log.LogInformation($&quot;Schedule: {myTimer.Schedule.ToString()}&quot;);
    log.LogInformation($&quot;Schedule Status Last: {myTimer.ScheduleStatus.Last.ToString()}&quot;);
    log.LogInformation($&quot;Schedule Status Next: {myTimer.ScheduleStatus.Next.ToString()}&quot;);
    log.LogInformation($&quot;Schedule Status LastUpdated: {myTimer.ScheduleStatus.LastUpdated.ToString()}&quot;);
    try
    {
       string eventHubConnectionString = Environment
         .GetEnvironmentVariable(&quot;csharpguitar_RootManageSharedAccessKey_EVENTHUB&quot;);
       log.LogInformation($&quot;eventHubConnectionString: {eventHubConnectionString}&quot;);
       var connectionStringBuilder = new EventHubsConnectionStringBuilder(eventHubConnectionString)
       {
          EntityPath = &quot;brain&quot;
       };
       eventHubClient = EventHubClient.CreateFromConnectionString(connectionStringBuilder.ToString());
       var date = DateTime.Now;
       var message = $&quot;A-message-from-Timer-trigger-{date.Hour}-{date.Minute}&quot;;
       log.LogInformation($&quot;Sending message: {message}&quot;);
       eventHubClient.SendAsync(new EventData(Encoding.UTF8.GetBytes(message))).Wait();
       eventHubClient.Close();
     }
     catch (EventHubsCommunicationException ehce)
     {
       log.LogInformation($&quot;EventHubsCommunicationException: {ehce.Message}&quot;);
     }
     catch (EventHubsException ehe)
     {
       log.LogInformation($&quot;EventHubsException: {ehe.Message}&quot;);
     }
     catch (Exception ex)
     {
       log.LogInformation($&quot;{DateTime.Now} &gt; Exception: {ex.Message}&quot;);
     }
}
[/sourcecode]

</div>
Now wait for 2 minutes and you should then see the following output in the Logs window for the Timer trigger.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:810ce56d-ca2c-482f-9bde-db315d49fdbd" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
[Information] Executing 'Functions.TimerTrigger' (Reason='Timer fired at 2018-10-16T13:54', Id=...6eea)
2018-10-16T13:54:00.078 [Information] C# Timer trigger function executed at: 10/16/2018 1:54:00 PM
2018-10-16T13:54:00.078 [Information] TimerInfo Methods:...
2018-10-16T13:54:00.079 [Information] TimerInfo Members:...
2018-10-16T13:54:00.080 [Information] Boolean IsPastDue
2018-10-16T13:54:00.080 [Information] Is past due: False
2018-10-16T13:54:00.080 [Information] Schedule: Cron: '0 0,2,4,6,8,10,12,14,16,18,... * * * *'
2018-10-16T13:54:00.080 [Information] Schedule Status Last: 10/16/2018 1:52:00 PM
2018-10-16T13:54:00.081 [Information] Schedule Status Next: 10/16/2018 1:54:00 PM
2018-10-16T13:54:00.081 [Information] Schedule Status LastUpdated: 10/16/2018 1:52:00 PM
2018-10-16T13:54:00.081 [Information] eventHubConnectionString: 
    Endpoint=sb://....servicebus.windows.net/;
    SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=QhYa8=;EntityPath=brain
2018-10-16T13:54:00.081 [Information] Sending message: A-message-from-Timer-trigger-13-54
2018-10-16T13:54:03.514 [Information] Executed 'Functions.TimerTrigger' (Succeeded, Id=...6eea)
[/sourcecode]

</div>
Something similar in the Logs window of the Event Hub trigger.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e14390c3-bc81-47e5-9ec4-40e7ccf932a2" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-16T13:54:03.515 [Information] Executing 'Functions.EventHubTrigger' (Reason='', Id=...d715)
2018-10-16T13:54:03.585 [Information] C# Event Hub trigger function 
                                      processed a message: A-message-from-Timer-trigger-13-54
2018-10-16T13:54:03.586 [Information] Message = A-message-from-Timer-trigger-13-54
2018-10-16T13:54:03.586 [Information] System Properties EnqueuedTimeUtc = 10/16/2018 1:54:02 PM
2018-10-16T13:54:03.586 [Information] System Properties Offset = 7472
2018-10-16T13:54:03.586 [Information] System Properties PartitionKey =
2018-10-16T13:54:03.586 [Information] System Properties SequenceNumber = 139
2018-10-16T13:54:03.586 [Information] The blob connection string is: ...
2018-10-16T13:54:03.586 [Information] The blob name is: A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:03.586 [Information] The blob content is: Hello, World! It's currently 10/16/2018 1:54:02PM
2018-10-16T13:54:03.586 [Information] The blob has been uploaded.
2018-10-16T13:54:03.587 [Information] Executed 'Functions.EventHubTrigger' (Succeeded, Id=...d715)
[/sourcecode]

</div>
And finally, this in the Blob trigger Log window.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:74d3bebc-2be8-46cc-94e2-05bc773f9dd1" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
[Information] Executing 'Functions.BlobTrigger' 
             (Reason='New blob detected: csharpguitar/A-message-from-Timer-trigger-13-54.txt', Id=...aafe)
2018-10-16T13:54:13.686 [Information] The name of the blob is: A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.686 [Information] Name: 
              AbsolutePath Value: /csharpguitar/A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.686 [Information] Name: 
              AbsoluteUri Value: https://.../../A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.686 [Information] Name: 
              LocalPath Value: /csharpguitar/A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.688 [Information] About to delete: A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.688 [Information] Deleting: A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.694 [Information] Deleted: A-message-from-Timer-trigger-13-54.txt
2018-10-16T13:54:13.695 [Information] Executed 'Functions.BlobTrigger' (Succeeded, Id=...aafe)
[/sourcecode]

</div>
And of course you can look at the graphical representation of the logs by clicking the Monitor link for each of the functions.

Congratulations, you have now configured, developed and consumed an Azure Function to run every 2 minutes that sends a message to an Event Hub which then stores the message as a blob, which triggers a blob Azure Function that dumps its properties and deletes it.

Finally, disable the timer so you do not consume the resources for no reason, see Figure 6.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image72.png"><img width="557" height="290" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb73.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to monitor an Azure Function with a Timmer trigger</span></strong>]]></content:encoded>
    </item>
    <item>
      <title>Azure Function - Service Bus</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-function-service-bus</link>
      <pubDate>Fri, 02 Nov 2018 15:17:46 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=30375</guid>
      <description><![CDATA[This lab has been moved to its new home...]]></description>
      <content:encoded><![CDATA[This lab has been moved to its new home here: https://benperk.github.io/azure/training/azure-function-service-bus.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with a Service Bus.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus" rel="noopener">here</a> “Azure Service Bus bindings for Azure Functions” which discusses the Service Bus trigger in detail so I will not readdress that content.  There is also a helpful article <a target="_blank" href="https://docs.microsoft.com/en-us/azure/event-grid/compare-messaging-services" rel="noopener">here</a> “Choose between Azure services that deliver messages” that discusses some difference between Event Grid (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-grid" rel="noopener">*</a>), Event Hub (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-hubs" rel="noopener">*</a>) and Service Bus (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus" rel="noopener">*</a>).  As per that article, use a Service Bus when the following are essential.<strong></strong><strong></strong>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top"><strong> Purpose</strong></td>
<td valign="top"><strong> Type</strong></td>
<td valign="top"><strong> When to use</strong></td>
</tr>
<tr>
<td valign="top">High-value enterprise messaging</td>
<td valign="top">Message</td>
<td valign="top">Order processing and financial transactions</td>
</tr>
</tbody>
</table>
&nbsp;

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.
<h1>Create a Service Bus</h1>
NOTE – to complete this lab you will need an Service Bus Namespace and a Service Bus Queue, follow <a target="_blank" href="https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues" rel="noopener">these</a> instructions to create the namespace and queue.  For this lab, I have created something similar to that shown in Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image61.png"><img width="855" height="387" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb60.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with a Service Bus trigger</span></strong>

I.e. my Service Bus Namespace is <strong>csharpguitar-servicebus</strong> that include a queue named <strong>brain</strong>.  Like Event Hub, the endpoint uses the sb:// protocol and has a hostname pattern containing *.servicebus.windows.net.
<h1>Create a Service Bus triggered Azure Function</h1>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image62.png"><img width="855" height="334" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb61.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with a Service Bus trigger</span></strong>

Then find and select the Event Hub trigger template, as seen in Figure 3.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image63.png"><img width="513" height="273" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb62.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with a Service Bus trigger</span></strong>

Install the <strong>Microsoft.Azure.WebJobs.Extension.ServiceBus </strong>extension, if prompted.  Once installed, check that the following extension has been added to your extensions.csproj file.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:c80b5a3b-bb9b-466e-858f-ddd87762ca58" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
&lt;ItemGroup&gt;
   &lt;PackageReference Include=&quot;Microsoft.Azure.WebJobs.Extensions.ServiceBus&quot; Version=&quot;3.0.0&quot; /&gt;
&lt;/ItemGroup&gt;
[/sourcecode]

</div>
Next, select the <em>new</em> link (see Figure 5) to create an Service Bus connection.  When the <em>new</em> link is selected, you will be prompted by a windows similar to that seen in Figure 4.  The Service Bus connection will contain the RootManageSharedAccessKey which is part of the Service Bus connection string and accessible via the “csharpguitar_RootManageSharedAccessKey_SERVICEBUS” application setting.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image64.png"><img width="482" height="229" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb63.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with a Service Bus trigger</span></strong>

Finally, similar as that seen in Figure 5, give the function a <strong>Name</strong> and add the the <strong>Queue Name</strong> which you created (review Figure 1).  Create the function by pressing the Create button.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image65.png"><img width="486" height="468" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb64.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with a Service Bus trigger</span></strong>

Once created you get the default Run() method shown here.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6ac1505a-1ac4-45bd-96ec-b5344e0e2298" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
using System;
using System.Threading.Tasks;

public static void Run(string myQueueItem, ILogger log)
{
    log.LogInformation($&quot;C# ServiceBus queue trigger function processed message: {myQueueItem}&quot;);
}
[/sourcecode]

</div>
This article <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#trigger---message-metadata" rel="noopener">here</a> “Azure Service Bus bindings for Azure Functions” identify the metadata properties available to the Service Bus triggered Azure Function.  This metadata are the properties present within the Microsoft.ServiceBus.Messaging class described <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.brokeredmessage?view=azure-dotnet" rel="noopener">here</a>. See also Microsoft.Azure.Service.Message <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.servicebus.message?view=azure-dotnet" rel="noopener">here</a> and Microsoft.Azure.WebJobs.ServiceBus.
<h1>Lab 13</h1>
Using those properties metadata, update the function code to resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:638f5cbd-2f1e-43fb-a771-fec39548862d" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
using System;
using System.Threading.Tasks;

public static void Run(string myQueueItem, Int32 DeliveryCount, string DeadLetterSource, 
        DateTime ExpiresAtUtc, DateTime EnqueuedTimeUtc, string MessageId, 
        string ContentType, string ReplyTo, Int64 SequenceNumber, string To, 
        string Label, string CorrelationId, ILogger log)
{    
    try
    {
       log.LogInformation($&quot;C# ServiceBus queue trigger function processed message: {myQueueItem}&quot;);
       log.LogInformation($&quot;DeliveryCount: {DeliveryCount}&quot;);
       log.LogInformation($&quot;DeadLetterSource: {DeadLetterSource}&quot;);
       log.LogInformation($&quot;ExpiresAtUtc: {ExpiresAtUtc}&quot;);
       log.LogInformation($&quot;EnqueuedTimeUtc: {EnqueuedTimeUtc}&quot;);
       log.LogInformation($&quot;MessageId: {MessageId}&quot;);
       log.LogInformation($&quot;ContentType: {ContentType}&quot;);
       log.LogInformation($&quot;ReplyTo: {ReplyTo}&quot;);
       log.LogInformation($&quot;SequenceNumber: {SequenceNumber}&quot;);
       log.LogInformation($&quot;To: {To}&quot;);
       log.LogInformation($&quot;Label: {Label}&quot;);
       log.LogInformation($&quot;CorrelationId: {CorrelationId}&quot;);
    }
    catch (Exception ex)
    {
       log.LogInformation($&quot;Something happened: {ex.Message}&quot;);
    }
}
[/sourcecode]

</div>
Run the AzureFunctionsConsumer and select the following to add a message to a Service Bus Queue which will trigger the Azure Function, Figure 6.  You will find the value for “Enter your Service Bus connection string:” as the <strong>VALUE</strong> item for “csharpguitar-servicebus_RootManageSharedAccessKey_SERVICEBUS” (or the VALUE of the name which you gave it, review Figure 5). Note that the value for “Enter your Queue name” should equal the Queue name you set previously in Figure 5 as well.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image66.png"><img width="855" height="575" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb65.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with an Event Hub trigger</span></strong>

The output, when triggered, resembles something like the following.  You can also view the output via the Monitor blade for the given Function.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:01c45331-52da-40a3-94ff-09d41d1dc6fe" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-18T12:17:34.188 [Information] 
  Executing 'Functions.ServiceBusQueueTrigger' 
  (Reason='New ServiceBus message detected on 'brain'.', Id=...ee1b)
2018-10-18T12:17:34.188 [Information] 
  C# ServiceBus queue trigger function processed message: Message-0-44307ab3e2d444b299589171fa9e2d88-17
2018-10-18T12:17:34.188 [Information] DeliveryCount: 1
2018-10-18T12:17:34.188 [Information] DeadLetterSource:
2018-10-18T12:17:34.188 [Information] ExpiresAtUtc: 11/1/2018 12:17:34 PM
2018-10-18T12:17:34.189 [Information] EnqueuedTimeUtc: 10/18/2018 12:17:34 PM
2018-10-18T12:17:34.189 [Information] MessageId: 6beec117be604aca850c19f7d035efd6
2018-10-18T12:17:34.189 [Information] ContentType:
2018-10-18T12:17:34.189 [Information] ReplyTo:
2018-10-18T12:17:34.189 [Information] SequenceNumber: 61361544922923034
2018-10-18T12:17:34.189 [Information] To:
2018-10-18T12:17:34.189 [Information] Label:
2018-10-18T12:17:34.189 [Information] CorrelationId:
2018-10-18T12:17:34.189 [Information] 
  Executed 'Functions.ServiceBusQueueTrigger1' (Succeeded, Id=...ee1b)
[/sourcecode]

</div>
NOTES:

I noticed that I could use the same endpoint pattern with my Event Hub Azure Function as a used with my Service Bus endpoint.  Where the protocol was sb:// and the host name contained *.servicebus.windows.net.  meaning to me that they are both built on the same platform but each serve a different purpose.
<h1>Lab 13.1</h1>
Before preceding with this lab make sure you have completed Lab 1, take note of the blob endpoint and container name created in Lab 1.  In this lab you will configure the Service Bus Queue trigger to store the message as a blob using the client SDK.

Update the Azure Function code so that it resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f1921591-beeb-4ee5-b667-9021563c8310" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.WindowsAzure.Storage&quot;

using System;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

private static CloudBlobClient blobClient;

public static void Run(string myQueueItem, Int32 DeliveryCount, string DeadLetterSource, 
        DateTime ExpiresAtUtc, DateTime EnqueuedTimeUtc, string MessageId, 
        string ContentType, string ReplyTo, Int64 SequenceNumber, string To, 
        string Label, string CorrelationId, ILogger log)
{    
    try
    {
       log.LogInformation($&quot;C# ServiceBus queue trigger function processed message: {myQueueItem}&quot;);
       log.LogInformation($&quot;DeliveryCount: {DeliveryCount}&quot;);
       log.LogInformation($&quot;DeadLetterSource: {DeadLetterSource}&quot;);
       log.LogInformation($&quot;ExpiresAtUtc: {ExpiresAtUtc}&quot;);
       log.LogInformation($&quot;EnqueuedTimeUtc: {EnqueuedTimeUtc}&quot;);
       log.LogInformation($&quot;MessageId: {MessageId}&quot;);
       log.LogInformation($&quot;ContentType: {ContentType}&quot;);
       log.LogInformation($&quot;ReplyTo: {ReplyTo}&quot;);
       log.LogInformation($&quot;SequenceNumber: {SequenceNumber}&quot;);
       log.LogInformation($&quot;To: {To}&quot;);
       log.LogInformation($&quot;Label: {Label}&quot;);
       log.LogInformation($&quot;CorrelationId: {CorrelationId}&quot;);

       var blobConnectionString = Environment.GetEnvironmentVariable(&quot;AzureWebJobsStorage&quot;);
       log.LogInformation($&quot;The blob connection string is: {blobConnectionString}&quot;);
       CloudStorageAccount storageAccount = CloudStorageAccount.Parse(blobConnectionString);
       blobClient = storageAccount.CreateCloudBlobClient();
       CloudBlobContainer blobContainer = blobClient.GetContainerReference(&quot;csharpguitar&quot;);
       log.LogInformation($&quot;The blob name is: {myQueueItem}.txt&quot;);
       CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference($&quot;{myQueueItem}.txt&quot;);
       log.LogInformation($&quot;The blob content is: Hello, World! It is currently {EnqueuedTimeUtc}&quot;);
       blockBlob.UploadTextAsync($&quot;Hello, World! It is currently {EnqueuedTimeUtc}&quot;);
       log.LogInformation($&quot;The blob has been uploaded.&quot;);
    }
    catch (StorageException se)
    {
       log.LogInformation($&quot;StorageException: {se.Message}&quot;);
    }
    catch (Exception ex)
    {
       log.LogInformation($&quot;Something happened: {ex.Message}&quot;);
    }
}
[/sourcecode]

</div>
Execute AzureFunctionsConsumer, same as before as seen in Figure 6, and review the results in the Logs.  Here you see that a message was sent to the the Service Bus Queue which in turn triggered the bound Azure Function.  You can also see the Information logs showing the name of the blob, it’s contents and the uploading of it.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2c22c23e-777c-464a-979b-ca4601667ceb" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-18T14:00:03.695 [Information] 
  Executing 'Functions.ServiceBusQueueTrigger' 
  (Reason='New ServiceBus message detected on 'brain'.', Id=..c7c)
2018-10-18T14:00:03.857 [Information] 
  C# ServiceBus queue trigger function processed message: Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59
2018-10-18T14:00:03.857 [Information] DeliveryCount: 1
2018-10-18T14:00:03.857 [Information] DeadLetterSource:
2018-10-18T14:00:03.857 [Information] ExpiresAtUtc: 11/1/2018 2:00:02 PM
2018-10-18T14:00:03.857 [Information] EnqueuedTimeUtc: 10/18/2018 2:00:02 PM
2018-10-18T14:00:03.858 [Information] MessageId: b7fbdf9f02224aca977583cccb24701b
2018-10-18T14:00:03.858 [Information] ContentType:
2018-10-18T14:00:03.858 [Information] ReplyTo:
2018-10-18T14:00:03.858 [Information] SequenceNumber: 20266198323167256
2018-10-18T14:00:03.858 [Information] To:
2018-10-18T14:00:03.858 [Information] Label:
2018-10-18T14:00:03.858 [Information] CorrelationId:
2018-10-18T14:00:03.858 [Information] The blob connection string is:...
2018-10-18T14:00:03.864 [Information] The blob name is: Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:03.864 [Information] The blob content is: Hello, World! It's currently 10/18/2018 2:00:02 PM
2018-10-18T14:00:03.865 [Information] The blob has been uploaded.
2018-10-18T14:00:03.867 [Information] Executed 'Functions.ServiceBusQueueTrigger1' (Succeeded, Id=...c7c)
[/sourcecode]

</div>
You can also see that the blob was uploaded to the blob storage container “csharpguitar” which triggered the blob trigger function.  Notice the timestamps are similar, and file name is the same in both logs.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:8d89a693-05eb-4ca0-bb4c-5d8b8b38b1a2" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-18T14:00:07.302 [Information] 
  Executing 'Functions.BlobTrigger' 
  (Reason='New blob detected: csharpguitar/Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt', 
Id=..2f6a)
2018-10-18T14:00:07.316 [Information] 
  The name of the blob is: Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.316 [Information] 
  Name: AbsolutePath Value: /csharpguitar/Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.322 [Information] 
  Name: AbsoluteUri Value: https://.../csharpguitar/Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.322 [Information] 
  Name: LocalPath Value: /csharpguitar/Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.322 [Information] Name: Authority Value: ...
2018-10-18T14:00:07.322 [Information] Name: HostNameType Value: Dns
2018-10-18T14:00:07.322 [Information] Name: IsDefaultPort Value: True
2018-10-18T14:00:07.333 [Information] About to delete: Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.333 [Information] Deleting: Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.343 [Information] Deleted: Message-0-2a0d771f637f4e40b1b34e9b2f495bd4-59.txt
2018-10-18T14:00:07.343 [Information] Executed 'Functions.BlobTrigger' (Succeeded, Id=...2f6a)
[/sourcecode]

</div>
Check the Monitor link and page to see similar output.

Have both Functions open in different tabs with the Log window open so you can see the logs, in real time during execution.

Congratulations, you have now configured, developed and consumed an Azure Function with an inbound Service Bus Queue trigger and coded the upload of a blob to a container which triggered another function.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image67.png"><img width="855" height="281" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb66.png" border="0" /></a>]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions - Storage Queue</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-storage-queue</link>
      <pubDate>Fri, 02 Nov 2018 15:09:07 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=30225</guid>
      <description><![CDATA[This lab has been moved to its new home here:...]]></description>
      <content:encoded><![CDATA[This lab has been moved to its new home here:  https://benperk.github.io/azure/training/azure-functions-storage-queue.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with a Storage Queue.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue" rel="noopener">here</a> “Azure Queue storage bindings for Azure Functions” which discusses the Storage Queue trigger in detail so I will not readdress that content.

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.
<h1>Create a Storage Queue</h1>
*NOTE – to complete this lab you will need an Storage Account.

By default, a storage account is created when the Azure Function is created, as seen in Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb111.png"><img width="357" height="110" title="image_thumb11" style="margin: 0px;border: 0px currentcolor" alt="image_thumb11" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb11_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with an Queue trigger</span></strong>

If you would like to store the queues into a different account, use <a target="_blank" href="https://docs.microsoft.com/en-us/azure/storage/queues/storage-dotnet-how-to-use-queues" rel="noopener">this</a> set of instruction to create an Azure Storage Account.  For this lab, you do not need to create the storage queue as the code in the AzureFunctionConsumer will do this for you later.
<h1>Create a Queue triggered Azure Function</h1>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image56.png"><img width="855" height="334" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb55.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with an Queue trigger</span></strong>

Then find and select the Queue trigger template, as seen in Figure 3.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image57.png"><img width="535" height="278" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb56.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with an Queue trigger</span></strong>

Install the <strong>Microsoft.Azure.WebJobs.Extension.Storage</strong> extension, if prompted.  Once installed, check that the following extension has been added to your extensions.csproj file.
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:44f48366-38a0-49b4-bdb5-9a24c07338fc" style="margin: 0px;padding: 0px;float: none">
<pre>&lt;ItemGroup&gt;
    &lt;PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.0" /&gt;
&lt;/ItemGroup&gt;</pre>
</div>
Once complete, continue to the next step.

<strong>TIP:</strong> If you ever need to install an extension manually, add the extension to the extensions.csproj file and run the following command in KUDU/SCM.
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cf853765-793a-40cb-9435-d5d69d04e5b3" style="margin: 0px;padding: 0px;float: none">
<pre>dotnet build extensions.csproj -o bin --no-incremental --packages D:\home\.nuget</pre>
</div>
Next, give the New Function a <strong>Name</strong>, add the <strong>Queue name</strong> (to be created later), leave <strong>Storage account connection</strong> ‘as-is’.  The storage account connection is, as titled, the Application Setting Name that contains the connection string for the storage account or will contain the storage queue added in the Queue name.  See Figure 4.  If you want this to be stored in a different container click on <em>new</em> and configure it.  Otherwise, press the <strong>Create</strong> button.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image58.png"><img width="601" height="543" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb57.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with an Queue trigger</span></strong>

Here is the default Run() method.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:17dcbfbb-183c-431f-8a43-bd827be1423a" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
using System;

public static void Run(string myQueueItem, ILogger log)
{
    log.LogInformation($&quot;C# Queue trigger function processed: {myQueueItem}&quot;);
}
[/sourcecode]

</div>
As mentioned in this article <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue#trigger---message-metadata" rel="noopener">here</a> “Azure Queue storage bindings for Azure Functions” the metadata properties available to the Azure Function are those present in the Microsoft.WindowsAzure.Storage.Queue class described <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.queue.cloudqueuemessage?view=azure-dotnet" rel="noopener">here</a>.
<h1>Lab 11</h1>
Using those properties metadata, update the function code to resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7f695069-a6e8-405b-a066-93319202d900" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.WindowsAzure.Storage&quot;

using System;
using Microsoft.WindowsAzure.Storage.Queue;

public static void Run(CloudQueueMessage myQueueItem, ILogger log)
{
    log.LogInformation($&quot;AsString: {myQueueItem.AsString}&quot;);
    log.LogInformation($&quot;DequeueCount: {myQueueItem.DequeueCount}&quot;);
    log.LogInformation($&quot;ExpirationTime: {myQueueItem.ExpirationTime}&quot;);
    log.LogInformation($&quot;Queue message Id: {myQueueItem.Id}&quot;);
    log.LogInformation($&quot;InsertionTime: {myQueueItem.InsertionTime}&quot;);
    log.LogInformation($&quot;CurrentTime: {DateTime.Now}&quot;);
    log.LogInformation($&quot;MaxMessageSize: {CloudQueueMessage.MaxMessageSize}&quot;);
    log.LogInformation($&quot;MaxNumberOfMessagesToPeek: {CloudQueueMessage.MaxNumberOfMessagesToPeek}&quot;);
    log.LogInformation($&quot;MaxVisibilityTimeout: {CloudQueueMessage.MaxVisibilityTimeout}&quot;);
    log.LogInformation($&quot;NextVisibleTime: {myQueueItem.NextVisibleTime}&quot;);
    log.LogInformation($&quot;PopReceipt: {myQueueItem.PopReceipt}&quot;);
}
[/sourcecode]

</div>
The items to note here are:
<ol>
 	<li>I included the reference to Microsoft.WindowsAzure.Storage (CloudQueueMessage classes) and the Microsoft.WindowsAzure.Storage.Queue for static access to MaxMessageSize, MaxNumberOfMessagesToPeek and MaxVisibilityTimeout.</li>
</ol>
Run the AzureFunctionsConsumer and select the following to upload messages to the queue which will trigger the Azure Function, Figure 5.  You will find the value for “Enter your queue Storage connection string:” as the <strong>VALUE</strong> item for “AzureWebJobsStorage” used when creating the function. Note that the value for “Enter the Storage Queue name:” should equal the Queue name you set previously, see Figure 4.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image59.png"><img width="855" height="582" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb58.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with an Queue trigger</span></strong>

The output, when triggered, resembles something like the following.  You can also view the output via the Monitor blade for the given Function.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:c269e31a-817d-4e93-b41b-7b93c0306a4a" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
[Information] Executing 
  'Functions.QueueTrigger' (Reason='New queue message detected on 'csharpguitar'.', Id=...78ed)
2018-10-17T08:01:25.267 [Information] AsString: Message 0
2018-10-17T08:01:25.267 [Information] DequeueCount: 1
2018-10-17T08:01:25.267 [Information] ExpirationTime: 10/24/2018 8:01:24 AM +00:00
2018-10-17T08:01:25.267 [Information] Queue message Id: 61d4e9a5-dfce-4ab2-b3fe-dff24588af54
2018-10-17T08:01:25.267 [Information] InsertionTime: 10/17/2018 8:01:24 AM +00:00
2018-10-17T08:01:25.267 [Information] CurrentTime: 10/17/2018 8:01:25 AM
2018-10-17T08:01:25.267 [Information] MaxMessageSize: 65536
2018-10-17T08:01:25.268 [Information] MaxNumberOfMessagesToPeek: 32
2018-10-17T08:01:25.268 [Information] MaxVisibilityTimeout: 7.00:00:00
2018-10-17T08:01:25.268 [Information] NextVisibleTime: 10/17/2018 8:11:25 AM +00:00
2018-10-17T08:01:25.268 [Information] PopReceipt: AgAAAAMAAAAAAAAAmR1u//Bl1AE=
2018-10-17T08:01:25.269 [Information] Executed 'Functions.QueueTrigger' (Succeeded, Id=...78ed)
[/sourcecode]

</div>
The Monitor blade for the given Function, as seen in Figure 6.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image60.png"><img width="855" height="245" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb59.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with an Queue trigger</span></strong>

NOTES:

Both queues and blobs can be stored in the same Azure Storage Account.  Within the account you can create a <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction">blob</a> container, a <a href="https://docs.microsoft.com/en-us/azure/storage/queues/storage-queues-introduction">queue</a>, a <a href="https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction">file</a> share and a <a href="https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-overview">table</a>, for example.

From a blob perspective, the function is notified when one is added and the location and how to access is sent to the function allowing processing.  Unlike the Queue, where the message is deleted after processing, the blob is not deleted when the Azure Function is triggered.

The default contents of the function.json file.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5d7dafb6-554c-4446-b748-c7eac41f595f" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="xml" autolinks="false" gutter="false" toolbar="false"]
{
  &quot;bindings&quot;: [
   {
     &quot;name&quot;: &quot;myQueueItem&quot;,
     &quot;type&quot;: &quot;queueTrigger&quot;,
     &quot;direction&quot;: &quot;in&quot;,
     &quot;queueName&quot;: &quot;csharpguitar&quot;,
     &quot;connection&quot;: &quot;AzureWebJobsStorage&quot;
   }
  ],
  &quot;disabled&quot;: false
}
[/sourcecode]

</div>
Congratulations, you have now configured, created and consumed an inbound request to an Azure Function.]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions - Microsoft Graph</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-microsoft-graph</link>
      <pubDate>Fri, 02 Nov 2018 15:03:00 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=30095</guid>
      <description><![CDATA[This lab has been moved to its new home...]]></description>
      <content:encoded><![CDATA[This lab has been moved to its new home here: https://benperk.github.io/azure/training/azure-functions-microsoft-graph.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with a Microsoft Graph.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-microsoft-graph" rel="noopener">here</a> “Microsoft Graph bindings for Azure Functions” which discusses the Microsoft Graph in detail so I will not readdress that content.
<h1>Azure Active Directory Tenant</h1>
Every Azure subscription will have an associated Azure Active Directory (AAD) tenant, it has the pattern similar to *.onmicrosoft.com.  Where * is the unique identifier created with your subscription.  There are other ways of getting an AAD tenant, like via O365, but that is outside the scope of this lab.

In order to complete this lab you will need to be authorized to Grant consent to permissions.  I.e. the first time you are authenticated, after configuring the Azure Function, you get prompted with a pop-up similar to that shown here, Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image47.png"><img width="356" height="390" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb46.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with Microsoft Graph</span></strong>

If you do not have this permission, after clicking the ‘Consent on behalf of your organization’ and pressing the Accept button, you will get the following error.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2f528d74-5b2d-45b6-be8b-dab5a3065086" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
AADSTS90094: An administrator of has set a policy that prevents you from granting &quot;app name&quot; the permissions 
it is requesting. Contact an administrator.
[/sourcecode]

</div>
You can check if your identity has the permission in the portal looking at the API permissions of the Application which you will create later.  If the ‘Grant admin consent for *****’ button is enabled, it means you have the permission, if not, well, you don’t, Figure 2, and you will need to be granted permission.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image48.png"><img width="855" height="341" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb47.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with Microsoft Graph</span></strong>
<h1>Create an Azure Function for access to Microsoft Graph on behalf of</h1>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 3.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image49.png"><img width="855" height="334" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb48.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with Microsoft Graph</span></strong>

Then find and select the Microsoft Graph template, as seen in Figure 4.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image50.png"><img width="484" height="246" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb49.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with Microsoft Graph</span></strong>

Install the <strong>Microsoft.Azure.WebJobs.Extension.AuthTokens </strong>extension, if prompted.  Once installed, check that the following extension has been added to your extensions.csproj file.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6f2537b8-6564-4b4a-ba21-79aa97ada63a" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
&lt;ItemGroup&gt;
  &lt;PackageReference Include=&quot;Microsoft.Azure.WebJobs.Extensions.AuthTokens&quot; Version=&quot;3.0.0&quot; /&gt;
&lt;/ItemGroup&gt;
[/sourcecode]

</div>
Next, select the <em>Configure AAD now </em>link (see Figure 5) to setup EasyAuth and set the permissions for this application in the tenant.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image51.png"><img width="477" height="560" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb50.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with Microsoft Graph</span></strong>

Once the automated configuration is complete, press the Create button to create the Function, Figure 6.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image52.png"><img width="476" height="476" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb51.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with Microsoft Graph</span></strong>

The configuration create an app registration into the AAD with a name similar to the Azure Function App name, Figure 7.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image53.png"><img width="855" height="231" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb52.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 7, how to create an Azure Function with Microsoft Graph</span></strong>

Here is the default Run() method.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:563ea5fe-1521-4ac8-86fe-4d3eb2cec643" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
using System.Net; 
using System.Net.Http; 
using System.Net.Http.Headers;

public static async Task&lt;HttpResponseMessage&gt; Run(HttpRequestMessage req, string graphToken, ILogger log)
{
   log.LogInformation(&quot;C# HTTP trigger function processed a request.&quot;); 
   HttpClient client = new HttpClient();
   client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(&quot;Bearer&quot;, graphToken);
   return await client.GetAsync(&quot;https://graph.microsoft.com/v1.0/me/photo/$value&quot;);
}
[/sourcecode]

</div>
**Make sure that you require AAD authentication “Log In with Azure Active Directory” for the function via the Authentication / Authorization link found on the Platform tab for the Azure Function App, Figure 8.  By default, it is set to allow anonymous.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image54.png"><img width="855" height="323" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb53.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 8, how to create an Azure Function with Microsoft Graph</span></strong>

I received a 500 when the authentication allowed anonymous.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image55.png"><img width="473" height="98" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb54.png" border="0" /></a>

If you receive this error when you access the Function from a browser:
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ea7b8218-738f-49c6-9b8e-56020e0d5156" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
{
   &quot;error&quot;: {
     &quot;code&quot;: &quot;OrganizationFromTenantGuidNotFound&quot;,
     &quot;message&quot;: &quot;The tenant for tenant guid '####' does not exist.&quot;,
     &quot;innerError&quot;: {
        &quot;request-id&quot;: &quot;####&quot;,
        &quot;date&quot;: &quot;2018-10-30T10:55:55&quot;
     }
   }
}
[/sourcecode]

</div>
Then you need to manually update the additionalLoginParams using resource explorer <a target="_blank" href="https://resources.azure.com" rel="noopener">here</a>.  The Application Id is the one shown previously in Figure 7, I marked it out with a black line with orange dots.  It is unique per registration.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:c8288520-6ac8-48cc-a113-4217dc791e5c" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
https://resources.azure.com/subscriptions/&lt;&gt;/resourceGroups/&lt;&gt;/providers/
      Microsoft.Web/sites/&lt;&gt;/config/authsettings/list
      &quot;additionalLoginParams&quot;: [&quot;response_type=code id_token&quot;,
      &quot;resource=&lt;AAD application ID&gt;&quot;],
[/sourcecode]

</div>
Again, the application ID is the GUID for the application permission configured into AAD when creating the Function, see Figure 5, 6.

If you access the Azure Function now from a <strong>browser</strong> you will get the following error.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7256c281-9bfd-4373-bb10-e0a77e04fbda" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
{
     &quot;error&quot;: {
     &quot;code&quot;: &quot;UnknownError&quot;,
     &quot;message&quot;: &quot;&quot;,
     &quot;innerError&quot;: {
        &quot;request-id&quot;: &quot;10445a2f-860e-467d-824f-215ed653b067&quot;,
        &quot;date&quot;: &quot;2018-10-29T13:18:28&quot;
     }
   }
}
[/sourcecode]

</div>
This is because the $value being returned is a binary data for the signed in user and not the actual image.  The client requesting the image will need to know how to work with that.
<h1>Lab 8</h1>
Update the line of code starting with “return await…” to the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:8c787185-12b2-4a3e-ab88-1983cc84f7c1" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
return await client.GetAsync(&quot;https://graph.microsoft.com/v1.0/me/&quot;);
[/sourcecode]

</div>
Then you can enter the URL to the Microsoft Graph configured Azure Function into a <strong>browser</strong> and you will get the results of your profile as stored in your AAD tenant.  View/Confirm the details in the portal by clicking on Azure Active Directory –&gt; Users –&gt; Your Profile.  The output of the Function with be something similar to the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:23cda745-9e43-47c6-bc8d-339998cb07ba" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
{&quot;@odata.context&quot;:&quot;https://graph.microsoft.com/v1.0/$metadata#users/$entity&quot;,
&quot;id&quot;:&quot;...0821d4f&quot;,&quot;businessPhones&quot;:],&quot;displayName&quot;:&quot;Benjamin Perkins)&quot;,&quot;givenName&quot;:
&quot;Benjamin&quot;,&quot;jobTitle&quot;:&quot;Cool&quot;,&quot;mail&quot;:null,&quot;mobilePhone&quot;:null,&quot;officeLocation&quot;:null,
&quot;preferredLanguage&quot;:null,&quot;surname&quot;:&quot;Perkins&quot;,
&quot;userPrincipalName&quot;:&quot;benjamin_...#EXT#@&lt;&gt;.onmicrosoft.com&quot;}
[/sourcecode]

</div>]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions - HTTP Trigger</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-http-trigger</link>
      <pubDate>Fri, 02 Nov 2018 14:56:25 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=29905</guid>
      <description><![CDATA[This lab has been moved to its new home here:...]]></description>
      <content:encoded><![CDATA[This lab has been moved to its new home here:  https://benperk.github.io/azure/training/azure-functions-http-trigger.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with an HTTP Trigger.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook" rel="noopener">here</a> “Azure Functions HTTP triggers and bindings” which discusses the HTTP Trigger in detail so I will not readdress that content.

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.

For this lab, you will use <strong>Visual Studio</strong> to create, code and deploy the Azure Function HTTP trigger.

In order to create Azure Functions in Visual Studio (I am using VS2017 Community), you need to install the “Azure Functions and Web Jobs Tools” extension.  To achieve that, in Visual Studio select Tools –&gt; Extensions and Updates… menu items and install it.  You will see something similar to the following, Figure 1

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image36.png"><img width="855" height="224" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb35.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with an HTTP trigger</span></strong>

Then, select New –&gt; Project and Azure Function, as shown in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image37.png"><img width="855" height="422" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb36.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with an HTTP trigger</span></strong>

Then select the HTTP Trigger template from the next window, Figure 3.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image38.png"><img width="855" height="518" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb37.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with an HTTP trigger</span></strong>

Here is the default Run() method.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:08af1166-5b0a-4610-9285-1d018f2e77ed" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
[FunctionName(&quot;Function1&quot;)]
public static async Task&lt;IActionResult&gt; 
Run([HttpTrigger(AuthorizationLevel.Function, &quot;get&quot;, &quot;post&quot;, Route = null)]HttpRequest req, ILogger log)
{
   log.LogInformation(&quot;C# HTTP trigger function processed a request.&quot;);
   string name = req.Query[&quot;name&quot;];
   string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
   dynamic data = JsonConvert.DeserializeObject(requestBody);
   name = name ?? data?.name;
   return name != null
      ? (ActionResult)new OkObjectResult($&quot;Hello, {name}&quot;)
      : new BadRequestObjectResult(&quot;Please pass a name on the query string or in the request body&quot;);
}
[/sourcecode]

</div>
NOTE, when you publish the trigger with the above code, the function name will be that which is included in the FunctionName declaration, I.e. Function1.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:1c8c0aec-a5eb-4eab-9f9b-b4db6fa2868b" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
[FunctionName(&quot;Function1&quot;)]
[/sourcecode]

</div>
You can change that name to be more elegant.  I.e. change Function1 to “CoolHttpTrigger” or something…
<h1>Lab 7</h1>
In this lab you will run and consume the HTTP triggered function on your local workstation.  Press the Run button or F5 to startup the Function Job Host.  When running you will see a window, similar to that shown in Figure 4.  This is the HOST which provides the access to the function.  It is what has to startup when you are running on the Azure platform.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image39.png"><img width="855" height="745" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb38.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with an HTTP trigger</span></strong>

Figure 5 is a representation of the Job Host and its dependencies which get loaded into the HOST, which then contains the Function Assemblies, Bindings (ex: WindowsAzure.Storage) and the Function dependencies.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image40.png"><img width="855" height="238" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb39.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with an HTTP trigger</span></strong>

Notice the URL that is in the red rectangle in Figure 4.  Open up a new cmd window and consume that URL using curl (or from a different browser instance/tab), as seen in Figure 6.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:f66a1e77-9230-4725-bf93-46647a4866e1" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
curl http :// localhost:7071/api/HttpTrigger?name=Benjamin
[/sourcecode]

</div>
<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image41.png"><img width="855" height="185" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb40.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with an HTTP trigger</span></strong>

As you can see from the default source code above, the trigger is expecting a parameter called ‘name’ and the code uses that value to send back a friendly Hello message.  Isn’t that nice, very polite, thank you.
<h1>Lab 7.1</h1>
In this lab you will deploy the HTTP trigger to the Azure platform and consume it using the <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">AzureFunctionConsumer</a>.

Right-click on the project name and select Publish… as seen in Figure 7.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image42.png"><img width="576" height="278" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb41.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 7, how to create an Azure Function with an HTTP trigger</span></strong>

Select the Create New radio button and then Publish, Figure 8.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image43.png"><img width="616" height="272" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb42.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 8, how to create an Azure Function with an HTTP trigger</span></strong>

Then make the selections and press the Create button, Figure 9.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image44.png"><img width="617" height="661" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb43.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 9, how to create an Azure Function with an HTTP trigger</span></strong>

Once successfully deployed, navigate to the Azure Portal (<a target="_blank" href="https://portal.azure.com" rel="noopener">*</a>) and click on the function you just deployed.  You will see something like the following.  Click on that link to get the URL and the function key which is necessary to consume or trigger the HTTP function.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cde268bd-5d8f-47f3-ab88-153ca31f4609" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
&lt;/&gt; Get function URL
[/sourcecode]

</div>
Run the AzureFunctionsConsumer and select the following to consume / trigger the HTTP function, Figure 10.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image45.png"><img width="855" height="671" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb44.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 10, how to create an Azure Function with an HTTP trigger</span></strong>

The output, when triggered, resembles something like the following.  You can also view the output via the Monitor blade for the given Function.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:21ff35fd-189a-467e-aeb2-98e997c34312" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-17T11:05:06.362 [Information] Executing 'HttpTrigger' 
   (Reason='This function was programmatically called via the host APIs.', Id=...cf522)
2018-10-17T11:05:06.363 [Information] C# HTTP trigger function processed a request.
2018-10-17T11:05:06.414 [Information] Executed 'HttpTrigger' (Succeeded, Id=...cf522)
[/sourcecode]

</div>
<h1>Lab 7.2</h1>
In this lab you will send a message to the Queue Storage trigger created in Lab 11.  If you have not done that one yet, please do that one before you continue with this one…
<ul>
 	<li>Add the NuGet package:  WindowsAzure.Storage</li>
 	<li>Add the using keyword for:
<ul>
 	<li>Microsoft.WindowsAzure.Storage</li>
 	<li>Microsoft.WindowsAzure.Storage.Queue</li>
</ul>
</li>
 	<li>Update the code x2 to match your specific configuration (can you find them?)</li>
</ul>
Update the code of you HTTP trigger in Visual Studio as shown here.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:68df0373-4231-406a-84ad-6b850a2d034d" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
[FunctionName(&quot;Function1&quot;)]
public static async Task&lt;IActionResult&gt;
Run([HttpTrigger(AuthorizationLevel.Function, &quot;get&quot;, &quot;post&quot;, Route = null)]HttpRequest req, ILogger log)
{
   log.LogInformation(&quot;C# HTTP trigger function processed a request.&quot;);
   string name = req.Query[&quot;name&quot;];
   string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
   dynamic data = JsonConvert.DeserializeObject(requestBody);
   name = name ?? data?.name;
   var message = $&quot;Message-From-{name}-HTTP-Trigger-{DateTime.Now.Minute}&quot;;

   try
   {
      log.LogInformation($&quot;Sending message: {message}&quot;);
      var StorageQueueConnectionString = Environment.GetEnvironmentVariable(&quot;AzureWebJobsStorage&quot;);
      CloudStorageAccount storageAccount = CloudStorageAccount.Parse(StorageQueueConnectionString);
      CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
      storageAccountQueue = queueClient.GetQueueReference(&quot;csharpguitar&quot;);
      await storageAccountQueue.AddMessageAsync(new CloudQueueMessage(message));
   }
   catch (StorageException se)
   {
      log.LogInformation($&quot;StorageException: {se.Message}&quot;);
   }
   catch (Exception ex)
   {
      log.LogInformation($&quot;{DateTime.Now} &gt; Exception: {ex.Message}&quot;);
   }

   return message != null
      ? (ActionResult)new OkObjectResult($&quot;This message, {message} was sent to the Message Queue&quot;)
      : new BadRequestObjectResult(&quot;Something bad happened, check the logs...&quot;);
}
[/sourcecode]

</div>
Then republish the HTTP trigger as previously explained, I.e Figure 7.  If you get “Publishing failed.”, Figure 11.  Restart the function and retry.  You can view the details of the exception in the Output window in Visual Studio.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image46.png"><img width="210" height="169" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb45.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 11, how to create an Azure Function with an HTTP trigger</span></strong>

Run the AzureFunctionsConsumer to consume / trigger the HTTP function, same as Figure 10, previously.  While running have the Logs console open for both functions in different browser windows.  You will see something similar to the following happening in close sequence, notice the timestamps…
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:8a04a6dc-b43a-435b-8188-bb75e7c536ca" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-17T12:03:13 Welcome, you are now connected to log-streaming service.
2018-10-17T12:04:11.767 [Information] 
  Executing 'HttpTrigger' (Reason='This function was programmatically called via the host APIs.', Id=...fcf)
2018-10-17T12:04:12.010 [Information] C# HTTP trigger function processed a request.
2018-10-17T12:04:12.011 [Information] Sending message: Message-From-Benjamin-HTTP-Trigger-4
2018-10-17T12:04:12.413 [Information] Executed 'HttpTrigger' (Succeeded, Id=...fcf)
[/sourcecode]

</div>
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:92f61a29-7587-426f-a512-f53c64657c8e" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-17T12:04:43.188 [Information] 
  Executing 'Functions.QueueTrigger' (Reason='New queue message detected on 'csharpguitar'.', Id=...7204)
2018-10-17T12:04:43.189 [Information] AsString: Message-From-Benjamin-HTTP-Trigger-4
2018-10-17T12:04:43.189 [Information] DequeueCount: 1
2018-10-17T12:04:43.189 [Information] ExpirationTime: 10/24/2018 12:04:12 PM +00:00
2018-10-17T12:04:43.189 [Information] Queue message Id: 55cd4cfb-f9ce-4c02-92b6-dfcc6d7bb348
2018-10-17T12:04:43.189 [Information] InsertionTime: 10/17/2018 12:04:12 PM +00:00
2018-10-17T12:04:43.190 [Information] CurrentTime: 10/17/2018 12:04:43 PM
2018-10-17T12:04:43.190 [Information] MaxMessageSize: 65536
2018-10-17T12:04:43.190 [Information] MaxNumberOfMessagesToPeek: 32
2018-10-17T12:04:43.190 [Information] MaxVisibilityTimeout: 7.00:00:00
2018-10-17T12:04:43.190 [Information] NextVisibleTime: 10/17/2018 12:14:43 PM +00:00
2018-10-17T12:04:43.190 [Information] PopReceipt: AgAAAAMAAAAAAAAAk2V5/BJm1AE=
2018-10-17T12:04:43.190 [Information] Executed 'Functions.QueueTrigger' (Succeeded, Id=...7204)
[/sourcecode]

</div>
Congratulations, you have now configured, coded, published and consumed an HTTP triggered Azure Function, using Visual Studio that sends the message to an Azure Storage Queue.]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions - Event Hub</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-event-hub</link>
      <pubDate>Fri, 02 Nov 2018 14:47:55 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=29675</guid>
      <description><![CDATA[This lab has been migrated to its new home here:...]]></description>
      <content:encoded><![CDATA[This lab has been migrated to its new home here:  https://benperk.github.io/azure/training/azure-functions-event-hub.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with an Event Hub.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-hubs" rel="noopener">here</a> “Azure Event Hubs bindings for Azure Functions” which discusses the Event Hub trigger in detail so I will not readdress that content.  There is also a helpful article <a target="_blank" href="https://docs.microsoft.com/en-us/azure/event-grid/compare-messaging-services" rel="noopener">here</a> “Choose between Azure services that deliver messages” that discusses some difference between Event Grid (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-grid" rel="noopener">*</a>), Event Hub (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-hubs" rel="noopener">*</a>) and Service Bus (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus" rel="noopener">*</a>).  As per that article, use an Event Hub when the following are essential.<strong></strong><strong>
</strong>
<table border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top"><strong>P urpose</strong></td>
<td valign="top"><strong> Type</strong></td>
<td valign="top"><strong> When to use</strong></td>
</tr>
<tr>
<td valign="top">Big data pipeline</td>
<td valign="top">Event streaming (series)</td>
<td valign="top">Telemetry and distributed data streaming</td>
</tr>
</tbody>
</table>
&nbsp;

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.
<h1>Create an Event Hub</h1>
*NOTE – to complete this lab you will need an Event Hub Namespace and an Event Hub, follow <a target="_blank" href="https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-create" rel="noopener">these</a> instructions to create the namespace and hub.  For this lab, I have created something similar to that shown in Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image25.png"><img width="855" height="454" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb24.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with an Event Hub trigger</span></strong>

I.e. my Event Hub Namespace is <strong>csharpguitar</strong>, that includes a hub named <strong>brain</strong>.  Like Service Bus, the endpoint uses the sb:// protocol and has a hostname pattern containing *.servicebus.windows.net.
<h1>Create an Event Hub triggered Azure Function</h1>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb71.png"><img width="855" height="337" title="image_thumb7" style="margin: 0px;border: 0px currentcolor" alt="image_thumb7" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb7_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with an Event Hub trigger</span></strong>

Then find and select the Event Hub trigger template, as seen in Figure 3.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image26.png"><img width="459" height="243" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb25.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with an Event Hub trigger</span></strong>

Install the <strong>Microsoft.Azure.WebJobs.Extension.EventHubs </strong>extension, if prompted.  Once installed, check that the following extension has been added to your extensions.csproj file.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:647f7482-288e-46c6-a315-6d0c92094b2d" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="xml" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
&lt;ItemGroup&gt;
   &lt;PackageReference Include=&quot;Microsoft.Azure.WebJobs.Extensions.EventHubs&quot; Version=&quot;3.0.0&quot; /&gt;
&lt;/ItemGroup&gt;
[/sourcecode]

</div>
Next, select the <em>new</em> link (see Figure 5) to create an Event Hub connection.  When the new link is selected, you will be prompted by a window similar to that seen in Figure 4.  The Event Hub connection will contain the RootManageSharedAccessKey which is part of the Event Hub connection string and accessible via the “csharpguitar_RootManageSharedAccessKey_EVENTHUB” application setting.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image27.png"><img width="639" height="168" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb26.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with an Event Hub trigger</span></strong>

Finally, similar as that seen in Figure 5, give the function a <strong>Name</strong>, leave <strong>Event Hub consumer group</strong> set to $Default and add the the <strong>Event Hub Name</strong> which you created (review Figure 1) and selected in Figure 4.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image28.png"><img width="456" height="499" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb27.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with an Event Hub trigger</span></strong>

Once created you get the default Run() method shown here.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5cd57fc3-4eb4-4cbc-91cc-6622c561fd2d" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
using System;

public static void Run(string myEventHubMessage, ILogger log)
{
    log.LogInformation($&quot;C# Event Hub trigger function processed a message: {myEventHubMessage}&quot;);
}
[/sourcecode]

</div>
This article <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-hubs#trigger---event-metadata" rel="noopener">here</a> “Azure Event Hubs bindings for Azure Functions” identify the metadata properties available to the Event Hub triggered Azure Function.  This metadata are the properties present within the Microsoft.Azure.EventHubs class described <a target="_blank" href="https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.EventHubs" rel="noopener">here</a>.
<h1>Lab 4</h1>
Using those properties metadata, update the function code to resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0521097e-49ea-42d9-8a55-19094fc6f1a0" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.Azure.EventHubs&quot;

using System;
using System.Text;
using Microsoft.Azure.EventHubs;

public static void Run(EventData myEventHubMessage, ILogger log)
{
log.LogInformation($&quot;C# Event Hub trigger function processed a message: {myEventHubMessage}&quot;);
log.LogInformation($&quot;Message = {Encoding.UTF8.GetString(myEventHubMessage.Body)}&quot;);
foreach(KeyValuePair&lt;string, object&gt; props in myEventHubMessage.Properties)
{
log.LogInformation($&quot;Properties Key = {props.Key }&quot;);
log.LogInformation($&quot;Properties Value = {props.Value}&quot;);
}
log.LogInformation(&quot;System Properties EnqueuedTimeUtc = &quot; +
$&quot;{myEventHubMessage.SystemProperties.EnqueuedTimeUtc}&quot;);
log.LogInformation($&quot;System Properties Offset = {myEventHubMessage.SystemProperties.Offset}&quot;);
log.LogInformation($&quot;System Properties PartitionKey = {myEventHubMessage.SystemProperties.PartitionKey}&quot;);
log.LogInformation(&quot;System Properties SequenceNumber = &quot; +
$&quot;{myEventHubMessage.SystemProperties.SequenceNumber}&quot;);
}
[/sourcecode]

</div>
The items to note are:
<ol>
 	<li>I include a reference to the Microsoft.Azure.EventHubs assembly.</li>
 	<li>I changed the type of myEventHubMessage from string to EventData.</li>
</ol>
Run the AzureFunctionsConsumer and select the following to add a message to an Event Hub which will trigger the Azure Function, Figure 5.  You will find the value for “Enter your Event Hub connection string:” as the <strong>VALUE</strong> item for “csharpguitar_RootManageSharedAccessKey_EVENTHUB” (or the VALUE of the name which you gave it, review Figure 5). Note that the value for “Enter your Event Hub name” should equal the Event Hub name you set previously as well.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image29.png"><img width="855" height="518" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb28.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with an Event Hub trigger</span></strong>

Review the Event Hub and check the Messages metric and you will see the messages having been received, Figure 6.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image30.png"><img width="405" height="323" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb29.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with an Event Hub trigger</span></strong>

The Log output, when triggered, resembles something like the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:3c298ee9-6b3a-44c3-95b4-35ea64c46b52" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018 [Information] Executing 'Functions.EventHubTrigger' (Reason='', Id=0d-45cd-bb03-4daee348ab53)
2018-10-15T12:16:28.840  [Information] C# Event Hub trigger function processed a message: 
2018-10-15T12:16:28.840 [Information] Message = Message 0
2018-10-15T12:16:28.840 [Information] System Properties EnqueuedTimeUtc  = 10/15/2018 12:16:28 PM
2018-10-15T12:16:28.841 [Information] System Properties Offset  = 6064
2018-10-15T12:16:28.841 [Information] System Properties PartitionKey  =
2018-10-15T12:16:28.841 [Information] System Properties SequenceNumber  = 119
2018 [Information] Executed 'Functions.EventHubTrigger' (Succeeded, Id=-0d-45cd-bb03-4daee348ab53)
2018 [Information] Executing 'Functions.EventHubTrigger' (Reason='', Id=82-c680-40a7-9987-136b8ac59722)
2018-10-15T12:16:29.109 [Information] C# Event Hub trigger function processed a message:
2018-10-15T12:16:29.109 [Information] Message = Message 1
...
[/sourcecode]

</div>
You can also view the output via the Monitor blade for the given Function, as seen in Figure 7.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image31.png"><img width="855" height="288" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb30.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 7, how to monitor an Azure Function with an Event Hub trigger</span></strong>

I decompiled the code using Just Decompile, like I often do to find what properties and methods were available, as seen in Figure 8.  I could have used Reflection, but decided to mix things up a little.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image32.png"><img width="855" height="461" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb31.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 8, how to install Microsoft.Azure.EventHubs into an Azure Function with an Event Hub trigger</span></strong>

You can find the Microsoft.Azure.EventHubs assembly via <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2014/03/24/using-kudu-with-windows-azure-web-sites/" rel="noopener">KUDU/SCM</a> in the /bin folder

Since version 2, adding the DLL manually for the extensions is no longer required, as I discussed <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2017/04/13/how-to-add-assembly-references-to-an-azure-function-app/" rel="noopener">here</a> “How to add assembly references to an Azure Function App” I added the implicit #r for a custom assembly, but this is no longer required, in most cases, for the extensions.

NOTES:

I noticed that I could use the same endpoint pattern with my Event Hub Azure Function as used with my Service Bus endpoint.  Where the protocol was sb:// and the host name contained *.servicebus.windows.net.  meaning to me that they are both built on the same platform but each deliver a set of different capabilities.
<h1>Lab 4.1</h1>
Before proceeding with this lab make sure you have completed Lab 1 and Lab 1.1.  The blob trigger in that lab (Lab 1) will insert a blob and then delete it (Lab 1.1).  In this lab, you will upload a blob into an Azure Storage container using the Microsoft.WindowsAzure.Storage CloudBlobClient class.

Note that the function.json file remains default, as that is where you would declaratively configure a inbound or outbound trigger.  In this case you use the client SDK for runtime outbound activity.

Update the Azure Function code so that it resembles the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:98f95783-adcd-433b-91e8-1b3bb36bfea9" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.Azure.EventHubs&quot;
#r &quot;Microsoft.WindowsAzure.Storage&quot;

using System;
using System.Text;
using Microsoft.Azure.EventHubs;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

private static CloudBlobClient blobClient;

public static void Run(EventData myEventHubMessage, ILogger log)
{
  log.LogInformation($
      &quot;C# Event Hub trigger function processed a message: {
        Encoding.UTF8.GetString(myEventHubMessage.Body)}&quot;);
  log.LogInformation($&quot;Message = {Encoding.UTF8.GetString(myEventHubMessage.Body)}&quot;);
  foreach(KeyValuePair&lt;string, object&gt; props in myEventHubMessage.Properties)
  {
    log.LogInformation($&quot;Properties Key = {props.Key }&quot;);
    log.LogInformation($&quot;Properties Value = {props.Value}&quot;);
  }
  log.LogInformation($
      &quot;System Properties EnqueuedTimeUtc = {
      myEventHubMessage.SystemProperties.EnqueuedTimeUtc}&quot;);
  log.LogInformation($&quot;System Properties Offset = {myEventHubMessage.SystemProperties.Offset}&quot;);
  log.LogInformation($&quot;System Properties PartitionKey = {
      myEventHubMessage.SystemProperties.PartitionKey}&quot;);
  log.LogInformation($
      &quot;System Properties SequenceNumber = {myEventHubMessage.SystemProperties.SequenceNumber}&quot;);
  try
  {
    var blobConnectionString = Environment.GetEnvironmentVariable(&quot;AzureWebJobsStorage&quot;);
    log.LogInformation($&quot;The blob connection string is: {blobConnectionString}&quot;);
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(blobConnectionString);
    blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer blobContainer = blobClient.GetContainerReference(&quot;csharpguitar&quot;);
    log.LogInformation($&quot;The blob name is: {Encoding.UTF8.GetString(myEventHubMessage.Body)}.txt&quot;);
    CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference($
      &quot;{Encoding.UTF8.GetString(myEventHubMessage.Body)}.txt&quot;);
    log.LogInformation($
      &quot;The blob content is: Hello, World! It is currently {
      myEventHubMessage.SystemProperties.EnqueuedTimeUtc}&quot;);
    blockBlob.UploadTextAsync($
      &quot;Hello, World! It is currently {myEventHubMessage.SystemProperties.EnqueuedTimeUtc}&quot;);
    log.LogInformation($&quot;The blob has been uploaded.&quot;);
  }
  catch (StorageException se)
  {
    log.LogInformation($&quot;StorageException: {se.Message}&quot;);
  }
  catch (Exception ex)
  {
    log.LogInformation($&quot;{DateTime.Now} &gt; Exception: {ex.Message}&quot;);
  }    
}
[/sourcecode]

</div>
Execute AzureFunctionsConsumer, same as before as seen in Figure 5, and review the results in the Logs.  Here you see that a message was sent to the Event Hub which in turn triggered the bound Azure Function.  You can also see the Information logs showing the name of the blob, it’s contents and the uploading of it.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0c7b128f-b6ac-4a60-a8c0-0a50030de9c9" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018 [Information] Executing 'Functions.EventHubTrigger' (Reason='', Id=...04af)
2018-10-15T13:34:53.164 [Information] C# Event Hub trigger function processed a message: Message-0
2018-10-15T13:34:53.164 [Information] Message = Message-0
2018-10-15T13:34:53.164 [Information] System Properties EnqueuedTimeUtc  = 10/15/2018 1:34:52 PM
2018-10-15T13:34:53.164 [Information] System Properties Offset  = 6800
2018-10-15T13:34:53.164 [Information] System Properties PartitionKey  =
2018-10-15T13:34:53.164 [Information] System Properties SequenceNumber  = 133
2018-10-15T13:34:53.164 [Information] The blob connection string is: DefaultEndpointsProtocol=...
2018-10-15T13:34:53.165 [Information] The blob name is: Message-0.txt
2018-10-15T13:34:53.165 [Information] The blob content is: Hello, World! It's currently 10/15/2018 1:34:52 PM
2018-10-15T13:34:53.165 [Information] The blob has been uploaded.
2018-10-15T13:34:53.166 [Information] Executed 'Functions.EventHubTrigger' (Succeeded, Id=...04af)
[/sourcecode]

</div>
Click on the Monitor link for the Event Hub trigger and you will see the same, similar output, Figure 9.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image33.png"><img width="855" height="327" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb32.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 9, how to monitor an Azure Function with an Event Hub trigger</span></strong>

You can also see that the blob was uploaded to the blob storage container “csharpguitar” which triggered the blob trigger function.  Notice the timestamp and file name are the same, similar in both logs.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:0808b953-daa4-42e4-a4ed-989a783608bd" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018 [Information] 'Functions.BlobTrigger' (Reason='New blob detected: csharpguitar/Message-0.txt', Id=..3ca)
2018-10-15T13:34:55.861 [Information] The name of the blob is: Message-0.txt
2018-10-15T13:34:55.861 [Information] Name: AbsolutePath Value: /csharpguitar/Message-0.txt
2018-10-15T13:34:55 [Information] Name: AbsoluteUri Value: https:/...windows.net/csharpguitar/Message-0.txt
2018-10-15T13:34:55.861 [Information] Name: LocalPath Value: /csharpguitar/Message-0.txt
2018-10-15T13:34:55.861 [Information] Name: Authority Value: ....blob.core.windows.net
...
2018-10-15T13:34:55.864 [Information] About to delete: Message-0.txt
2018-10-15T13:34:55.869 [Information] Deleting: Message-0.txt
2018-10-15T13:34:55.870 [Information] Deleted: Message-0.txt
2018-10-15T13:34:55.870 [Information] Executed 'Functions.BlobTrigger' (Succeeded, Id=...3ca)
[/sourcecode]

</div>
Check the Monitor link and page to see similar output, Figure 10.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image34.png"><img width="855" height="270" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb33.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 10, how to monitor an Azure Function with an Event Hub trigger</span></strong>

Congratulations, you have now configured, developed and consumed an Azure Function with an inbound Event Hub and coded the upload of a blob to a container which triggered another function.  The flow is like that shown in Figure 11.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image35.png"><img width="855" height="270" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb34.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 11, how to monitor an Azure Function with an Event Hub trigger</span></strong>]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions - Azure Cosmos DB</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-azure-cosmos-db</link>
      <pubDate>Fri, 02 Nov 2018 14:31:57 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=29425</guid>
      <description><![CDATA[This article has been moved to its new home...]]></description>
      <content:encoded><![CDATA[This article has been moved to its new home here: https://benperk.github.io/azure/training/azure-functions-azure-cosmos-db.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with an Azure Cosmos DB.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-cosmosdb-v2" rel="noopener">here</a> “Azure Cosmos DB bindings for Azure Functions 2.x” which discusses the Cosmos DB trigger in detail so I will not readdress that content.

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.

When you want an Azure Function to execute when a document is added to a specified Cosmos DB this lab will get you started.  Additionally, here are 2 articles which are useful to get some more insight into this feature:
<ul>
 	<li><a target="_blank" href="https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-dotnet-samples" rel="noopener">Azure Cosmos DB: .NET examples for the SQL API</a></li>
 	<li><a target="_blank" href="https://github.com/Azure/azure-cosmosdb-dotnet/blob/master/samples/code-samples/DocumentManagement/Program.cs" rel="noopener">azure-cosmosdb-dotnet</a></li>
</ul>
<h1>Create a Cosmos Database</h1>
*NOTE – to complete this lab you will need an Azure Cosmos DB account, a Cosmos DB and a Collection.  Follow <a target="_blank" href="https://docs.microsoft.com/en-us/azure/cosmos-db/create-sql-api-dotnet" rel="noopener">these</a> instructions to create the account, database and collection.  For this lab, I have created something similar to that shown in Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image13.png"><img width="855" height="649" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb12.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Where <strong>csharpguitar</strong> is the Cosmos DB account, <strong>ToDoList</strong> is the database and <strong>Items</strong> is the collection.
<h1>Create an Azure Cosmos DB triggered Azure Function</h1>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image14.png"><img width="855" height="337" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb13.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Then find and select the Cosmos DB trigger template, as seen in Figure 3.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image15.png"><img width="508" height="266" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb14.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Install the <strong>Microsoft.Azure.WebJobs.Extensions.CosmosDB</strong> extension, if prompted.  Once installed, check that the following extension has been added to your extensions.csproj file.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:c8b44a92-3988-497a-a24c-5a539fa6cfc5" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="xml" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
&lt;ItemGroup&gt;
  &lt;PackageReference Include=&quot;Microsoft.Azure.WebJobs.Extensions.CosmosDB&quot; Version=&quot;3.0.0&quot; /&gt;
&lt;/ItemGroup&gt;
[/sourcecode]

</div>
Next, select the <em>new</em> link (see Figure 5) to create an Azure Cosmos DB connection.  When the <em>new</em> link is selected, you will be prompted by a windows similar to that seen in Figure 4.  You can view the Cosmos DB connection string on the Cosmos DB / Keys blade.  Once the select button is press the Cosmos DB connection string is stored in an Application Setting named for ex: csharpguitar_DOCUMENTDB.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image16.png"><img width="494" height="237" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb15.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Finally, similar as that seen in Figure 5, give the function a <strong>Name</strong>, add the <strong>Collection name</strong> as created in Figure 1, add the <strong>Database name</strong> also as created in Figure 1, then press the Create button to complete the function creation.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image17.png"><img width="496" height="698" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb16.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Once created you get the default Run() method shown here.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:ff2dab0e-1fc8-49b2-b282-b90bc2c1949a" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.Azure.DocumentDB.Core&quot;
using System;
using System.Collections.Generic;
using Microsoft.Azure.Documents;

public static void Run(IReadOnlyList&lt;Document&gt; input, ILogger log)
{
    if (input != null &amp;&amp; input.Count &gt; 0)
    {
        log.LogInformation(&quot;Documents modified &quot; + input.Count);
        log.LogInformation(&quot;First document Id &quot; + input[0].Id);
    }
}
[/sourcecode]

</div>
Notice that there is a variable of IReadOnlyList&lt;Microsoft.Azure.Documents.Document&gt; passed into the Run().  Let's find out what properties that Document object exposes.
<h1>Lab 2</h1>
Update the function code to resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:461c5207-9e4b-4109-b88b-c17471c44256" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.Azure.DocumentDB.Core&quot;
using System;
using System.Collections.Generic;
using Microsoft.Azure.Documents;

public static void Run(IReadOnlyList&lt;Document&gt; input, ILogger log)
{
    try
    {
        if (input != null &amp;&amp; input.Count &gt; 0)
        {
            var result = input.ToList();
            log.LogInformation($&quot;Documents modified {input.Count}&quot;);
            foreach (var document in result)
            {
                log.LogInformation($&quot;DocumentId {document.Id}&quot;);
                log.LogInformation($&quot;AltLink: {document.AltLink}&quot;);
                log.LogInformation($&quot;AttachmentsLink {document.AttachmentsLink}&quot;);
                log.LogInformation($&quot;ETag {document.ETag}&quot;);
                log.LogInformation($&quot;ResourceId {document.ResourceId}&quot;);
                log.LogInformation($&quot;SelfLink {document.SelfLink}&quot;);
                log.LogInformation($&quot;Timestamp {document.Timestamp}&quot;);
                log.LogInformation($&quot;TimeToLive {document.TimeToLive}&quot;);
            }
        } 
    }
    catch (Exception ex)
    {
        log.LogInformation($&quot;Something Happened: {ex.Message}&quot;);
    }       
}
[/sourcecode]

</div>
The items to note here are:
<ol>
 	<li>I originally included the reference to System.Reflection (Type and PropertyInfo classes), however the Document class has set the GetProperty() to private…  However, see Figure 6 where the Document class does expose GetMetaObject() method which will return return the properties rendered in the above code example.</li>
 	<li>The IReadOnlyList&lt;&gt; interface does not include an IEnummerable interface, so it gets casted to a List which can then be iterated through within a foreach loop.</li>
</ol>
<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image18.png"><img width="592" height="766" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb17.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Run the AzureFunctionsConsumer and select the following to upload documents which will trigger the Azure Function, Figure 7.  You will find the value for <strong>database</strong> name and <strong>collection</strong> name via the values you entered when creating your Cosmos DB, see Figure 1.  The <strong>endpoint url</strong> name is found on the Overview blade for the Cosmos DB account (URI).  The <strong>account key</strong> is found on the Keys blade for the given Cosmos DB account.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image19.png"><img width="855" height="841" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb18.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 7, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Check the Documents item on the Cosmos DB blade to see that the documents where indeed uploaded and view the contents of them, Figure 8.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image20.png"><img width="855" height="369" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb19.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 8, how to create an Azure Function with a Cosmos DB trigger</span></strong>

The Log output, when triggered, resembles something like the following.  You can also view the output via the Monitor blade for the given Function.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:fe514395-053c-4e73-b09d-6398d00b41f7" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-26T09:11:04.684 [Information] Executing 'Functions.CosmosTrigger' 
   (Reason='New changes on collection Items at 2018-10-26T09:11:04.6842733Z', Id=...78aa)
2018-10-26T09:11:05.015 [Information] Documents modified 4
2018-10-26T09:11:05.016 [Information] DocumentId 0
2018-10-26T09:11:05.016 [Information] AltLink: dbs/ToDoList/colls/Items/docs/0
2018-10-26T09:11:05.043 [Information] 
   AttachmentsLink dbs/BBcXAA==/colls/BBcXAOfHQgA=/docs/BBcXAOfHQgAlAAAAAAAAAA==/attachments/
2018-10-26T09:11:05.044 [Information] ETag &quot;0000c30a-0000-0000-0000-5bd2da240000&quot;
2018-10-26T09:11:05.044 [Information] ResourceId BBcXAOfHQgAlAAAAAAAAAA==
2018-10-26T09:11:05.044 [Information] 
   SelfLink dbs/BBcXAA==/colls/BBcXAOfHQgA=/docs/BBcXAOfHQgAlAAAAAAAAAA==/
2018-10-26T09:11:05.044 [Information] Timestamp 10/26/2018 9:11:00 AM
2018-10-26T09:11:05.044 [Information] TimeToLive
2018-10-26T09:11:05.044 [Information] DocumentId 1
2018-10-26T09:11:05.044 [Information] AltLink: dbs/ToDoList/colls/Items/docs/1
...
2018-10-26T09:11:05.045 [Information] DocumentId 2
2018-10-26T09:11:05.045 [Information] AltLink: dbs/ToDoList/colls/Items/docs/2
...
2018-10-26T09:11:05.045 [Information] DocumentId 3
2018-10-26T09:11:05.045 [Information] AltLink: dbs/ToDoList/colls/Items/docs/3
...
2018-10-26T09:11:05.050 [Information] Executed 'Functions.CosmosTrigger' 
   (Succeeded, Id=...78aa)
[/sourcecode]

</div>
The Monitor blade for the given Function, as seen in Figure 9, notice that there is a single log for all the documents uploaded during the connection.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image21.png"><img width="855" height="291" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb20.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 9, how to create an Azure Function with a Cosmos DB trigger</span></strong>

You have now configured, created and consumed an inbound request to an Azure Function, next, configure an outbound action in response to the inbound request.
<h1>Lab 2.1</h1>
In this lab you will update the Cosmos DB function trigger to select a document from the database, convert it to JSON and then display it to the Log console.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:bfef7dda-a568-4056-bbc9-1ad8ccb0ed2a" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.Azure.DocumentDB.Core&quot;
#r &quot;Newtonsoft.Json&quot;
using System;
using System.Collections.Generic;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Newtonsoft.Json;

private static DocumentClient client;

public static void Run(IReadOnlyList&lt;Document&gt; input, ILogger log)
{
    try
    {
        if (input != null &amp;&amp; input.Count &gt; 0)
        {
            var result = input.ToList();
            log.LogInformation($&quot;Documents modified {input.Count}&quot;);
            foreach (var document in result)
            {
                log.LogInformation($&quot;DocumentId {document.Id}&quot;);
                log.LogInformation($&quot;AltLink: {document.AltLink}&quot;);
                log.LogInformation($&quot;AttachmentsLink {document.AttachmentsLink}&quot;);
                log.LogInformation($&quot;ETag {document.ETag}&quot;);
                log.LogInformation($&quot;ResourceId {document.ResourceId}&quot;);
                log.LogInformation($&quot;SelfLink {document.SelfLink}&quot;);
                log.LogInformation($&quot;Timestamp {document.Timestamp}&quot;);
                log.LogInformation($&quot;TimeToLive {document.TimeToLive}&quot;);
            }
        }
        var endpointUrl = &quot;&lt;ADD URL&gt;&quot;;
        var authorizationKey = &quot;&lt;PRIMARY KEY&gt;&quot;;
        var databaseId = &quot;ToDoList&quot;;
        var collectionId = &quot;Items&quot;;

        client = new DocumentClient(new Uri(endpointUrl), authorizationKey);
        Database database = client.CreateDatabaseQuery()
            .Where(c =&gt; c.Id == databaseId).ToArray().FirstOrDefault();
        DocumentCollection collection = client.CreateDocumentCollectionQuery(database.SelfLink)
            .Where(c =&gt; c.Id == collectionId).ToArray().FirstOrDefault();
        Order order = client.CreateDocumentQuery&lt;Order&gt;(collection.SelfLink)
             .Where(o =&gt; o.Id == &quot;0&quot;).AsEnumerable().FirstOrDefault();
        if (order != null)
        {
            log.LogInformation($&quot;Order AccountNumber: {order.AccountNumber}&quot;);
            var output = JsonConvert.SerializeObject(order);
            log.LogInformation($&quot;JSON: {output}&quot;);
        }        
    }
    catch (DocumentClientException de)
    {
        Exception baseException = de.GetBaseException();
        log.LogInformation($&quot;{de.StatusCode} error: {de.Message}, Message: {baseException.Message}&quot;);
    }
    catch (Exception ex)
    {
        log.LogInformation($&quot;Something Happened: {ex.Message}&quot;);
    }       
}

public class Order
{
    [JsonProperty(PropertyName = &quot;id&quot;)]
    public string Id { get; set; }
    public DateTime CreateDate { get; set; }
    public string AccountNumber { get; set; }
    public decimal Freight { get; set; }
    public decimal TotalDue { get; set; }
    public OrderDetail[] Items { get; set; }
}

public class OrderDetail
{
    public int OrderQty { get; set; }
    public int ProductId { get; set; }
    public decimal UnitPrice { get; set; }
}
[/sourcecode]

</div>
The items to note here are:
<ol>
 	<li>I included an assembly reference for both <strong>Microsoft.Azure.DocumentDB.Core</strong> and <strong>Newtonsoft.Json</strong>.  Then I included them in my project via the using keyword.</li>
 	<li>Next using <strong>Microsoft.Azure.Documents.Client</strong> the client is instantiated, the query created and the result Serialized.</li>
</ol>
Run the AzureFunctionsConsumer and select the same as previously, Figure 7.  This time, upload only a single (1) document.

The output of the Logs console in the portal will look something similar to the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:a4cbd0e3-c191-4d7e-9c04-dbc8347d293b" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
2018-10-29T10:42:23.801 [Information] 
   Executing 'Functions.CosmosTrigger' 
   (Reason='New changes on collection Items at 2018-10-29T10:42:23.8003475Z', Id=...d25b)
2018-10-29T10:42:24.364 [Information] Documents modified 1
2018-10-29T10:42:24.370 [Information] DocumentId 0
2018-10-29T10:42:24.370 [Information] AltLink: dbs/ToDoList/colls/Items/docs/0
2018-10-29T10:42:24.371 [Information] AttachmentsLink
2018-10-29T10:42:24.371 [Information] ETag &quot;280038c4-0000-0000-0000-5bd6e40c0000&quot;
2018-10-29T10:42:24.371 [Information] ResourceId BBcXAOfHQgBSAAAAAAAAAA==
2018-10-29T10:42:24.371 [Information] SelfLink dbs/BBcXAA==/colls/BB..gA=/docs/BBcXA...AAAAAAAA==/
2018-10-29T10:42:24.371 [Information] Timestamp 10/29/2018 10:42:20 AM
2018-10-29T10:42:24.371 [Information] TimeToLive
2018-10-29T10:42:25.241 [Information] Order AccountNumber: Account0
2018-10-29T10:42:25.243 [Information] 
JSON: {
        &quot;id&quot;:&quot;0&quot;,
        &quot;CreateDate&quot;:&quot;2018-10-29T10:42:20.3381465+00:00&quot;,
        &quot;AccountNumber&quot;:&quot;Account0&quot;,
        &quot;Freight&quot;:472.3108,
        &quot;TotalDue&quot;:985.018,
        &quot;Items&quot;:[
        {
          &quot;OrderQty&quot;:0,
          &quot;ProductId&quot;:0,
          &quot;UnitPrice&quot;:419.4589}
]}
2018-10-29T10:42:25.243 [Information] Executed 'Functions.CosmosTrigger' (Succeeded, Id=...d25b)
[/sourcecode]

</div>
There are many actions take with a JSON file…try to come up with some ideas about how you can enhance this example or send the JSON body to another system, ask yourself also if this is the best architectural design for the solution.  Nice work, keep going.
<h1>Lab 2.2</h1>
To complete this lab, you need to first have completed Lab 1 and Lab 1.1.  In this lab you will:
<ul>
 	<li>Retrieve the uploaded document from the Cosmos DB</li>
 	<li>Declaratively configure an outbound action to store that file into the blob storage container configured in Lab 1.</li>
</ul>
To achieve this, select the Integrate link under the function created in Lab 2 and press the + New Output option, as seen in Figure 10.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image22.png"><img width="855" height="437" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb21.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 10, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Press the select button and options similar to that in Figure 11, are rendered.  Note the Blob parameter name and update the Path as shown…leave the Storage account connection as the default, assuming you made no change in Lab 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image23.png"><img width="855" height="348" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb22.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 11, how to create an Azure Function with a Cosmos DB trigger</span></strong>

Save the outbound trigger.  Once save completes you will see the output binding in the interface, similiar to that shown in Figure 12.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image24.png"><img width="536" height="161" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb23.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 12, how to create an Azure Function with a Cosmos DB trigger</span></strong>

The functions.json file gets updated to include the output binding, similiar to that shown below.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:2c3ce4b9-563b-4615-976f-0b53823dcffc" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
{
   &quot;bindings&quot;: [
   {
     &quot;type&quot;: &quot;cosmosDBTrigger&quot;,
     &quot;name&quot;: &quot;input&quot;,
     &quot;direction&quot;: &quot;in&quot;,
     &quot;connectionStringSetting&quot;: &quot;csharpguitar_DOCUMENTDB&quot;,
     &quot;databaseName&quot;: &quot;ToDoList&quot;,
     &quot;collectionName&quot;: &quot;Items&quot;,
     &quot;leaseCollectionName&quot;: &quot;leases&quot;,
     &quot;createLeaseCollectionIfNotExists&quot;: true
   },
   {
     &quot;type&quot;: &quot;blob&quot;,
     &quot;name&quot;: &quot;outputBlob&quot;,
     &quot;path&quot;: &quot;csharpguitar/{name}&quot;,
     &quot;connection&quot;: &quot;AzureWebJobsStorage&quot;,
     &quot;direction&quot;: &quot;out&quot;
   }
 ]
}
[/sourcecode]

</div>
Update the Azure Function code so that it resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:bdecf957-f1c1-4c0c-a5da-6d258132f9e2" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
#r &quot;Microsoft.WindowsAzure.Storage&quot;
#r &quot;Microsoft.Azure.DocumentDB.Core&quot;
#r &quot;Newtonsoft.Json&quot;

using System;
using System.Collections.Generic;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.WindowsAzure.Storage.Blob;
using Newtonsoft.Json;

private static DocumentClient client;

public static void Run(IReadOnlyList&lt;Document&gt; input, CloudBlockBlob outputBlob, ILogger log)
{
    try
    {
        if (input != null &amp;&amp; input.Count &gt; 0)
        {
            var result = input.ToList();
            log.LogInformation($&quot;Documents modified {input.Count}&quot;);
            foreach (var document in result)
            {
                log.LogInformation($&quot;DocumentId {document.Id}&quot;);
                log.LogInformation($&quot;AltLink: {document.AltLink}&quot;);
                log.LogInformation($&quot;AttachmentsLink {document.AttachmentsLink}&quot;);
                log.LogInformation($&quot;ETag {document.ETag}&quot;);
                log.LogInformation($&quot;ResourceId {document.ResourceId}&quot;);
                log.LogInformation($&quot;SelfLink {document.SelfLink}&quot;);
                log.LogInformation($&quot;Timestamp {document.Timestamp}&quot;);
                log.LogInformation($&quot;TimeToLive {document.TimeToLive}&quot;);
            }
        }
        var endpointUrl = &quot;&lt;URL&gt;/&quot;;
        var authorizationKey = &quot;&lt;PRIMARY ACCESS KEY&gt;&quot;;
        var databaseId = &quot;ToDoList&quot;;
        var collectionId = &quot;Items&quot;;

        client = new DocumentClient(new Uri(endpointUrl), authorizationKey);
        Database database = client.CreateDatabaseQuery()
            .Where(c =&gt; c.Id == databaseId).ToArray().FirstOrDefault();
        DocumentCollection collection = client.CreateDocumentCollectionQuery(database.SelfLink)
            .Where(c =&gt; c.Id == collectionId).ToArray().FirstOrDefault();
        Order order = client.CreateDocumentQuery&lt;Order&gt;(collection.SelfLink)
            .Where(o =&gt; o.Id == &quot;0&quot;).AsEnumerable().FirstOrDefault();
        if (order != null)
        {
            log.LogInformation($&quot;Order AccountNumber: {order.AccountNumber}&quot;);
            log.LogInformation($&quot;Order: {order.ToString()}&quot;);
            log.LogInformation($&quot;About to insert: {order.AccountNumber}&quot;);
            log.LogInformation($&quot;Inserting: {order.AccountNumber}&quot;);
            outputBlob.UploadTextAsync(order.AccountNumber);
            log.LogInformation($&quot;Inserted: {order.AccountNumber}&quot;);
        }        
    }
    catch (DocumentClientException de)
    {
        Exception baseException = de.GetBaseException();
        log.LogInformation($&quot;{de.StatusCode} error: {de.Message}, Message: {baseException.Message}&quot;);
    }
    catch (Exception ex)
    {
        log.LogInformation($&quot;Something Happened: {ex.Message}&quot;);
    }       
}

public class Order
{
    [JsonProperty(PropertyName = &quot;id&quot;)]
    public string Id { get; set; }
    public DateTime CreateDate { get; set; }
    public string AccountNumber { get; set; }
    public decimal Freight { get; set; }
    public decimal TotalDue { get; set; }
    public OrderDetail[] Items { get; set; }
}

public class OrderDetail
{
    public int OrderQty { get; set; }
    public int ProductId { get; set; }
    public decimal UnitPrice { get; set; }
}
[/sourcecode]

</div>
In Lab 1.1 you added a DeleteAsync() method to the Azure Function, so consider removing that temporarily so you can look at the blob in the container.

Congratulations, you have again declaratively configured, developed and consumed an Azure Function with an inbound and outbound trigger.]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions - Blob Storage</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-blob-storage</link>
      <pubDate>Fri, 02 Nov 2018 13:52:31 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=29175</guid>
      <description><![CDATA[This lab has been moved to its new home here:...]]></description>
      <content:encoded><![CDATA[This lab has been moved to its new home here:  https://benperk.github.io/azure/training/azure-functions-blob-storage.html

The labs contained in this article show how to create, configure, code and monitor an Azure Function with a Blob Trigger.  There is a detailed document <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob" rel="noopener">here</a> “Azure Blob storage bindings for Azure Functions” which discusses the Blob storage trigger in detail so I will not readdress that content.

I have written an AzureFunctionConsumer program which I host on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a><span></span>.  You can use this code to consume the Azure Functions discussed in <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-labs-information-and-setup-instructions/" rel="noopener"><span>this</span> </a>series of articles.

When you want an Azure Function to execute when a blob is added to a specified storage container use <a target="_blank" href="https://github.com/Azure/azure-webjobs-sdk/blob/94c3b5fdb614df66900934b088eb68a228c57405/src/Microsoft.Azure.WebJobs.Extensions.Storage/Blobs/Triggers/BlobTriggerBinding.cs" rel="noopener">this</a> trigger type which is discussed in this lab.  (use this binding type for small working sets that are not time critical)   Here are some articles which I wrote about WebJobs/Blob storage:
<ul>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2016/05/03/how-i-back-up-my-azure-blob-storage-container/" rel="noopener">How (I) back up my Azure Blob Storage container</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2017/10/27/how-to-map-an-azure-app-service-web-app-virtual-directory-to-azure-storage-containter/" rel="noopener">How to map an Azure App Service Web App virtual directory to Azure Storage Container</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2014/12/01/upload-an-image-to-an-azure-blob-container-using-the-gadgeteer-part-1/" rel="noopener">Upload an image to an Azure Blob container using the Gadgeteer</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/07/19/system-diagnostics-trace-application-logging-log-stream-on-azure-app-service-function-app/" rel="noopener">System.Diagnostics.Trace Application Logging Log Stream on Azure App Service Function App</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2014/02/03/how-to-store-and-access-your-iis-logs-on-windows-azure-web-site/" rel="noopener">How to store and access your IIS Logs on Microsoft Azure App Service</a></li>
 	<li><a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/02/08/how-to-backuprestore-an-azure-app-service-using-azure-powershell/" rel="noopener">How to Backup/Restore an Azure App Service using Azure PowerShell</a></li>
</ul>
<h1>Create a Storage Account</h1>
*NOTE – to complete this lab you will need a Storage Account.

By default, a storage account is created when the Azure Function is created, as seen in Figure 1.  In a real, production scenario the blob container would likely not be the same as the one which stores the Function code.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image1.png"><img width="357" height="110" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with an Blob trigger</span></strong>

If you would like to store the blobs into a different account, use <a target="_blank" href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-portal" rel="noopener">this</a> set of instruction to create an Azure Storage Account.  For this lab, you do not need to create the storage container as the code in the AzureFunctionConsumer will do this for you later, but you can if you want.
<h1>Create a Blob triggered Azure Function</h1>
Add a new Function to the Function App by pressing the + sign next the the Functions menu item, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image2.png"><img width="855" height="337" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb1.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, how to create an Azure Function with an Blob trigger</span></strong>

Then find and select the Blob trigger template, as seen in Figure 2.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image3.png"><img width="411" height="220" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb2.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, how to create an Azure Function with an Blob trigger</span></strong>

Install the <strong>Microsoft.Azure.WebJobs.Extension.Storage</strong> extension, if prompted.  Once installed, check that the following extension has been added to your extensions.csproj file.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:44f48366-38a0-49b4-bdb5-9a24c07338fc" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="xml" autolinks="false" gutter="false" toolbar="false"]
&lt;ItemGroup&gt;
    &lt;PackageReference Include=&quot;Microsoft.Azure.WebJobs.Extensions.Storage&quot; Version=&quot;3.0.0&quot; /&gt;
&lt;/ItemGroup&gt;
[/sourcecode]

</div>
Once complete, continue to the next step.

<strong>TIP:</strong> If you ever need to install an extension manually, add the extension to the extensions.csproj file and run the following command in KUDU/SCM.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cf853765-793a-40cb-9435-d5d69d04e5b3" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
dotnet build extensions.csproj -o bin --no-incremental --packages D:\home\.nuget
[/sourcecode]

</div>
Next, give the New Function a <strong>Name</strong>, add the <strong>Path</strong> where the first attribute is the storage container name (can already exists or it will be created via the AzureFunctionConsumer) and leave {name} ‘as-is’.  {name} will the be the name of the blob stored in the container.  The storage account connection is, as titled, the App Setting Name that contains the connection string for the storage account which contains or will contain the storage container added in the Path.  See Figure 4.  If you want this to be stored in a different container click on <em>new</em> and configure it.  Otherwise, press the <strong>Create</strong> button.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image4.png"><img width="491" height="459" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb3.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, how to create an Azure Function with an Blob trigger</span></strong>

Here is the default Run() method.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:e5f0be42-cda2-4578-8511-0681bc30c005" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]
public static void Run(Stream myBlob, string name, ILogger log)
{
    log.LogInformation($&quot;C# Blob trigger function Processed blob Name:{name} Size: {myBlob.Length} Bytes&quot;);
}
[/sourcecode]

</div>
As mentioned in this article <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob#trigger---metadata" rel="noopener">here</a> “Azure Blob storage bindings for Azure Functions” the metadata properties available to the Azure Function are those present in the Microsoft.WindowsAzure.Storage.Blob class described <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob" rel="noopener">here</a>.  In addition, there are <strong>BlobTrigger</strong> (same as URI.AbsolutePath), <strong>Uri</strong>, <strong>Properties</strong> BlobProperties/CloudBlob(<a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.blobproperties?view=azure-dotnet" rel="noopener">*</a>/<a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.blob.cloudblob?view=azure-dotnet" rel="noopener">*</a>), and user-defined <strong>Metadata</strong> properties which are also accessible.  Lastly, a System.IO.<strong>Stream</strong> (<a target="_blank" href="https://msdn.microsoft.com/en-us/library/system.io.stream(v=vs.110).aspx" rel="noopener">*</a>) object is passed into the Run() which also provides some interesting information.
<h1>Lab 1</h1>
Using those properties metadata, update the function code to resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:b7897788-fcd7-4e3a-b7ea-be7d0d1cbe6e" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
using System.Collections;
using System.Reflection;

public static void Run(Stream myBlob, string name, Uri uri,
                       IDictionary&lt;string,string&gt; metadata, ILogger log)
{
    log.LogInformation($&quot;The name of the blob is: {name}&quot;);
    Type uriType = typeof(Uri);
    PropertyInfo[] properties = uriType.GetProperties();
    foreach (PropertyInfo uriProp in properties)
    {
        log.LogInformation($&quot;Name: {uriProp.Name} Value: {uriProp.GetValue(uri, null)}&quot;);
    }
    foreach(KeyValuePair&lt;string, string&gt; data in metadata)
    {
        log.LogInformation($&quot;User-Defined Metadata Key  = { data.Key  }&quot;);
        log.LogInformation($&quot;User-Defined Metadata Value  = { data.Value  }&quot;);
    }
    if (metadata.Count == 0) 
    {
        log.LogInformation(&quot;There were no user-defined metadata&quot;);
    }
    log.LogInformation($&quot;System.IO.Stream.CanRead is: {myBlob.CanRead}&quot;);
    log.LogInformation($&quot;System.IO.Stream.CanSeek is: {myBlob.CanSeek}&quot;);
    log.LogInformation($&quot;System.IO.Stream.CanTimeout is: {myBlob.CanTimeout}&quot;);
    log.LogInformation($&quot;System.IO.Stream.CanWrite is: {myBlob.CanWrite}&quot;);
    log.LogInformation($&quot;System.IO.Stream.Length is: {myBlob.Length}&quot;);
    log.LogInformation($&quot;System.IO.Stream.Position is: {myBlob.Position}&quot;);
}
[/sourcecode]

</div>
The items to note here are:
<ol>
 	<li>I included the reference to System.Reflection (Type and PropertyInfo classes) and System.Collections (KeyValuePair structure).</li>
 	<li>I used reflection to loop through the properties and values of the Uri class.</li>
</ol>
Run the AzureFunctionsConsumer and select the following to upload blobs which will trigger the Azure Function, Figure 5.  You will find the value for “Enter your blob Storage connection string:” as the <strong>VALUE</strong> item for “AzureWebJobsStorage” app setting used when creating the function. Note that the value for “Enter the Blob Container name:” should equal the Path you set previously (excluding the <em>{name}</em>), see Figure 4.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image5.png"><img width="855" height="600" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb4.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 5, how to create an Azure Function with an Blob trigger</span></strong>

Once executed, Navigate to the container that you configured to store the blobs, and you will see something similar to the following, Figure 6.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image6.png"><img width="855" height="351" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb5.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 6, how to create an Azure Function with an Blob trigger</span></strong>

The Log output, when triggered, resembles something like the following.  You can also view the output via the Monitor blade for the given Function.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image7.png"><img width="855" height="86" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb6.png" border="0" /></a>
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:6b0bb8e4-ae7d-416e-b11e-6e5620da3da4" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
[Info] Executing 'Functions.BlobTrigger' (Reason='New blob detected: csharpguitar/helloworld0.txt', Id=)
2018-10-12T13:03:20.676 [Information] The name of the blob is: helloworld0.txt
2018-10-12T13:03:20.676 [Information] Name: AbsolutePath Value: /csharpguitar/helloworld0.txt
2018-10-12T13:03:20.676 [Info] Name: AbsoluteUri Value: ...blob.core.windows.net/csharpguitar/helloworld0.txt
2018-10-12T13:03:20.676 [Information] Name: LocalPath Value: /csharpguitar/helloworld0.txt
2018-10-12T13:03:20.676 [Information] Name: Authority Value: myazurefunctionsstorage.blob.core.windows.net
2018-10-12T13:03:20.677 [Information] Name: HostNameType Value: Dns
2018-10-12T13:03:20.677 [Information] Name: IsDefaultPort Value: True
2018-10-12T13:03:20.677 [Information] Name: IsFile Value: False
2018-10-12T13:03:20.677 [Information] Name: IsLoopback Value: False
2018-10-12T13:03:20.677 [Information] Name: PathAndQuery Value: /csharpguitar/helloworld0.txt
[/sourcecode]

</div>
The Monitor blade for the given Function, as seen in Figure 7.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image8.png"><img width="855" height="323" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb7.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 7, how to create an Azure Function with an Blob trigger</span></strong>

NOTES:

Both queues and blobs can be stored in the same Azure Storage Account.  Within the account you can create a <a href="https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction">blob</a> container, a <a href="https://docs.microsoft.com/en-us/azure/storage/queues/storage-queues-introduction">queue</a>, a <a href="https://docs.microsoft.com/en-us/azure/storage/files/storage-files-introduction">file</a> share and a <a href="https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-overview">table</a>, for example.

From a blob perspective, the function is notified when one is added and the location and how to access is sent to the function allowing processing.  Unlike the Queue, where the message is deleted after processing, the blob is not deleted when the Azure Function is triggered.

The default contents of the function.json file.  Click on <em>View files</em> to see the function.json file in the portal.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:5af489c4-6240-4907-b185-cb00232b6478" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="xml" autolinks="false" gutter="false" toolbar="false"]
{
  &quot;bindings&quot;: [
    {
      &quot;name&quot;: &quot;myBlob&quot;,
      &quot;type&quot;: &quot;blobTrigger&quot;,
      &quot;direction&quot;: &quot;in&quot;,
      &quot;path&quot;: &quot;csharpguitar/{name}&quot;,
      &quot;connection&quot;: &quot;AzureWebJobsStorage&quot;
    }
  ]
}
[/sourcecode]

</div>
You have now configured, created and consumed an inbound request to an Azure Function, next, configure an outbound action in response to the inbound request.
<h1>Lab 1.1</h1>
In this lab you will configure an outbound action to delete the inserted blob that was inserted into the blob container configured in Lab 1.

To achieve this, select the Integrate link under the function created in Lab 1 and press the + New Output option, as seen in Figure 8.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image9.png"><img width="855" height="362" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb8.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 8, how to create an outbound Azure Function with an Blob trigger</span></strong>

Press the select button and options similar to that in Figure 9, are rendered.  Note the Blob parameter name and update the Path as shown…leave the Storage account connection as the default, assuming you made no change in Lab 1.<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image10.png"><img width="855" height="309" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb9.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 9, how to create an outbound Azure Function with an Blob trigger</span></strong>

Once saved you will see the output binding in the interface, similar to that shown in Figure 10.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image11.png"><img width="461" height="147" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb10.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 10, how to create an outbound Azure Function with an Blob trigger</span></strong>

The functions.json file gets updated to include the output binding, similar to that shown below.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:58035b60-294a-4d4c-a51a-a02fa6c677a3" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" padlinenumbers="true" autolinks="false" gutter="false" toolbar="false"]
{
  &quot;bindings&quot;: [
  {
    &quot;name&quot;: &quot;myBlob&quot;,
    &quot;type&quot;: &quot;blobTrigger&quot;,
    &quot;direction&quot;: &quot;in&quot;,
    &quot;path&quot;: &quot;csharpguitar/{name}&quot;,
    &quot;connection&quot;: &quot;AzureWebJobsStorage&quot;
  },
  {
    &quot;type&quot;: &quot;blob&quot;,
    &quot;name&quot;: &quot;outputBlob&quot;,
    &quot;path&quot;: &quot;csharpguitar/{name}&quot;,
    &quot;connection&quot;: &quot;AzureWebJobsStorage&quot;,
    &quot;direction&quot;: &quot;out&quot;
  }
 ]
}
[/sourcecode]

</div>
Update the Azure Function code so that it resemble the following.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:7ca8dd3b-7ed9-4275-99d5-9be38a2c37a5" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="csharp" autolinks="false" gutter="false" toolbar="false"]&lt;/pre&gt;
#r &quot;Microsoft.WindowsAzure.Storage&quot;

using System.Collections;
using System.Reflection;
using Microsoft.WindowsAzure.Storage.Blob; 
public static void Run(Stream myBlob, string name, Uri uri, CloudBlockBlob outputBlob,
           IDictionary&lt;string,string&gt; metadata, ILogger log)
{
     log.LogInformation($&quot;The name of the blob is: {name}&quot;);
     Type uriType = typeof(Uri);
     PropertyInfo[] properties = uriType.GetProperties();
     foreach (PropertyInfo uriProp in properties)
     {
       log.LogInformation($&quot;Name: {uriProp.Name} Value: {uriProp.GetValue(uri, null)}&quot;);
     }
     foreach(KeyValuePair&lt;string, string&gt; data in metadata)
     {
       log.LogInformation($&quot;User-Defined Metadata Key  = { data.Key  }&quot;);
       log.LogInformation($&quot;User-Defined Metadata Value  = { data.Value  }&quot;);
     }
     if (metadata.Count == 0)
     {
       log.LogInformation(&quot;There were no user-defined metadata&quot;);
     }
     log.LogInformation($&quot;System.IO.Stream.CanRead is: {myBlob.CanRead}&quot;);
     log.LogInformation($&quot;System.IO.Stream.CanSeek is: {myBlob.CanSeek}&quot;);
     log.LogInformation($&quot;System.IO.Stream.CanTimeout is: {myBlob.CanTimeout}&quot;);
     log.LogInformation($&quot;System.IO.Stream.CanWrite is: {myBlob.CanWrite}&quot;);
     log.LogInformation($&quot;System.IO.Stream.Length is: {myBlob.Length}&quot;);
     log.LogInformation($&quot;System.IO.Stream.Position is: {myBlob.Position}&quot;);
     
     log.LogInformation($&quot;About to delete: {name}&quot;);
     log.LogInformation($&quot;Deleting: {name}&quot;);
     outputBlob.DeleteAsync();
     log.LogInformation($&quot;Deleted: {name}&quot;);
}
[/sourcecode]

</div>
Notice the inclusion of the Microsoft.WindowsAzure.Storage / .Blob binary and reference.  This is required for the utilization of the CloudBlockBlob passed to the Run() method, which is used at the end of the method to access the DeleteAsync() method which removes the blob from the storage container.  Notice that the variable ‘outputBlob” in the parameters for the Run() method, matches the name of the output parameter of name in the function.json file.

Execute AzureFunctionsConsumer, same as before as seen in Figure 5, and review the results in the Logs.
<div class="wlWriterEditableSmartContent" id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:d8b6e568-598c-4fd4-8564-cbacb4ab8574" style="margin: 0px;padding: 0px;float: none">

[sourcecode language="text" autolinks="false" gutter="false" toolbar="false"]
2018-10-12T14:43:51.723 [Information] About to delete: helloworld3.txt
2018-10-12T14:43:51.723 [Information] Deleting: helloworld3.txt
2018-10-12T14:43:51.729 [Information] Deleted: helloworld3.txt
[/sourcecode]

</div>
And also, after some moments via the Monitor link for the function, see Figure 11

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image12.png"><img width="855" height="234" title="image" alt="image" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb11.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 11 how to create an outbound Azure Function with an Blob trigger</span></strong>

Confirm that the blobs have indeed been deleted by looking at the contents of the container, like in Figure 6.

Congratulations, you have now declaratively configured, developed and consumed an Azure Function with an inbound and outbound trigger.]]></content:encoded>
    </item>
    <item>
      <title>Azure Functions Labs - Information and setup instructions</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/azure-functions-labs-information-and-setup-instructions</link>
      <pubDate>Fri, 02 Nov 2018 13:23:59 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=28925</guid>
      <description><![CDATA[This post has been moved to its new home here:...]]></description>
      <content:encoded><![CDATA[This post has been moved to its new home here:  https://benperk.github.io/azure/training/azure-functions-labs-information-and-setup-instructions.html

As if writing some code wasn’t complicated enough, now you need to write it using patterns designed to run on the cloud platform and pick the most effective service or services to run it on.  By ‘service’ I mean PaaS, IaaS, Server-less, etc.… and by ‘cloud patterns’ I primarily mean that your code must recover from exceptions and ungraceful terminations super well (must be resilient).  There is plenty of documentation about writing good programs and cloud patterns, but not so many about which service you need to run your fault tolerant program on.  You already know what IaaS is so you know that you have complete control (and responsibility) over the operating system and anything running on top of that.  The cons of IaaS is the price conscience ability to scale quickly (up or out), the deployment and support is pretty much like it happens when running things yourself.  What you get is the network infrastructure.  When it comes to PaaS, there are a few different flavors on Azure.  Cloud Services which are going to deprecate at some point, but not soon?, has some hurdles when it comes to migrating existing applications to it.  There is no migrate button is what I mean and you pretty much have to cut and paste or start over to get your code there.  However, you do not have to worry about the operating system, security patches and scaling is much more cost friendly and dynamic.  In its prime, Cloud Services was the definition of ‘the cloud’.  The follower of Cloud Services is App Services.  I write many articles about this you might know, and it is simply one of the most unbelievable compute solutions in the history of mankind and computers.  An App Service runs within the confines of a sandbox (until you move to containers) that restricts some actions your program can perform.  There are not that many, but sometimes it is a problem.  The scalability (up and out) is very cost effective and the ‘issue’ concerning the ‘sandbox’ will be nonexistent once containers get into more mainstream (they are already actually).  Then we come to server-less computing.  I don’t yet completely get the cost model, but pretty much if you are running a small program, it is mostly free, you only need to get the code written and <strong>the features aligned</strong> to make it flow and function, which is the purpose of these labs.  I.e. create an Azure Function App that includes many Azure Functions so you learn why you might want to use each trigger type for inbound data object processing and maybe even find a reason to create outbound triggers that pass the output of the input to another Azure Function.  That thinking leads to <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/durable-functions-overview" rel="noopener">Durable Functions</a> I would imagine, which is something I will learn and document later.  Let’s get started.

I started my learning of Azure Functions, I.e. Service-less computing by writing this .NET Core Console application which calls the following Azure Functions each with a different trigger type.  I hosted the console application on GitHub <a target="_blank" href="https://github.com/benperk/AzureFunctionConsumer" rel="noopener">here</a>.  You will need the .NET Core runtime installed on your work station to run the console app, check <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2017/09/20/how-to-install-net-core-2-0/" rel="noopener">this</a> out.
<h1>Labs</h1>
Before beginning the following labs, be sure to complete the Getting Started section further down in this article.
<table border="1" cellspacing="0" cellpadding="1">
<tbody>
<tr>
<td valign="top">Lab Instructions</td>
<td valign="top">  Located here</td>
</tr>
<tr>
<td valign="top">Lab 1: Azure Functions - Blob Storage</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-blob-storage/" rel="noopener">Lab 1 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-blob-storage/" rel="noopener">Lab 1.1 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 2: Azure Functions - Cosmos DB</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-azure-cosmos-db/" rel="noopener">Lab 2 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-azure-cosmos-db/" rel="noopener">Lab 2.1 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-azure-cosmos-db/" rel="noopener">Lab 2.2 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-cosmosdb-v2" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 3: Azure Functions - Event Grid</td>
<td valign="top">  Lab 3 (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-grid" rel="noopener">*</a>)(<a target="_blank" href="https://docs.microsoft.com/en-us/azure/event-grid/compare-messaging-services" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 4: Azure Functions - Event Hub</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-event-hub/" rel="noopener">Lab 4 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-event-hub/" rel="noopener">Lab 4.1 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-hubs" rel="noopener">*</a>)(<a target="_blank" href="https://docs.microsoft.com/en-us/azure/event-grid/compare-messaging-services" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 5: Azure Functions – TBD</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 6: Azure Functions – TBD</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 7: Azure Functions - HTTP trigger</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-http-trigger/" rel="noopener">Lab 7 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-http-trigger/" rel="noopener">Lab 7.1 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-http-trigger/" rel="noopener">Lab 7.2 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 8: Azure Functions - Microsoft Graph</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-microsoft-graph/" rel="noopener">Lab 8 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-microsoft-graph" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 9: Azure Functions – TBD</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 10: Azure Functions – TBD</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 11: Azure Functions – Storage Queue</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-storage-queue/" rel="noopener">Lab 11 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-queue" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 12: Azure Functions - SendGrid</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 13: Azure Functions - Service Bus</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-function-service-bus/" rel="noopener">Lab 13 √</a>, <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-function-service-bus/" rel="noopener">Lab 13.1 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus" rel="noopener">*</a>)(<a target="_blank" href="https://docs.microsoft.com/en-us/azure/event-grid/compare-messaging-services" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 14: Azure Functions - SignalR Service</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 15: Azure Functions - Table Storage</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 16: Azure Functions - Timer</td>
<td valign="top">  <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/11/02/azure-functions-timer/" rel="noopener">Lab 16 √</a> (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer" rel="noopener">*</a>)</td>
</tr>
<tr>
<td valign="top">Lab 17: TBD</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 18: Durable Functions</td>
<td valign="top"></td>
</tr>
<tr>
<td valign="top">Lab 19: Binding expressions and patterns</td>
<td valign="top">  Lab 19 (<a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#binding-expressions-and-patterns" rel="noopener">*</a>) (6 x bullets)</td>
</tr>
</tbody>
</table>
&nbsp;

<strong><span>NOTE:</span></strong> For all of the trigger types an endpoint is a requirement.  An endpoint, in generic terms, is nothing more than a accessible unique identifier that is used trigger code.
<h1>.NET Framework vs. .NET Core Framework</h1>
Did you know Azure Functions 1.x runs(ran) with .NET Framework and 2.x runs with the .NET Core Framework
<h1>Azure Functions languages</h1>
Although these labs focus mostly on C#, because that is my favorite, you can write Azure Functions in many languages.  See the list <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-versions#languages" rel="noopener">here</a>.
<h1>Host.json</h1>
To be an expert in regards to Azure Functions, you need to know all the attributes and configurations possible for a Function App.  Read about them <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-host-json" rel="noopener">here</a> “host.json reference for Azure Functions”.  Note that the host.json file lives in the wwwroot directory of the Function App and is therefore a logical conclusion that changes to that file impact the Function App, I.e. not only the function.  There is a function.json file which can be used to make function specific configurations.  You must also recognize, perfect and understand the specific configurations per binding type.  Each trigger type has some unique settings, like:
<ul>
 	<li>maxBatchSize, prefetchCount, batchCheckpointFrequency</li>
 	<li>GatewayMode, Protocol, leasePrefix</li>
 	<li>and many, many more…</li>
</ul>
<h1>Bindings and integrations</h1>
Bindings in Azure Functions 1.0 were native which made them hard to update (.NET Framework 4.6).  It was difficult because the native bindings were bound to the runtime and making a change to the binding required a change to the runtime.  With Azure Function 2.0 (.NET Standard 2.0) the bindings can be versioned independent of the runtime and are developed separately.   This means each team can develop capabilities at their own pace.  Here is a list of Azure Function v2 bindings:
<ul>
 	<li>HTTP</li>
 	<li>Timer</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.Storage</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.ServiceBus</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.EventHubs</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.CosmosDB</li>
 	<li>Microsoft.Azure.WebJobs.Extensions..EventGrid</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.MicrosoftGraph</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.DurableTask</li>
 	<li>Microsoft.Azure.WebJobs.Extensions.SignalRService</li>
</ul>
When you create a trigger using one of the above types, you are prompted to install the required extension for the selected binding.  Something similar to that shown in Figure 1.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb2_thumb1.png"><img width="510" height="339" title="image_thumb2_thumb[1]" style="margin: 0px;border: 0px currentcolor" alt="image_thumb2_thumb[1]" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb2_thumb1_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 1, create an Azure Function App, installing extensions</span></strong>

The source code for the extensions is <a target="_blank" href="https://github.com/Azure/azure-webjobs-sdk-extensions" rel="noopener">here</a>.

The list of supported bindings are <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-versions#bindings" rel="noopener">here</a>.

<strong>TIP:</strong> If you ever need to install an extension manually, add the extension to the extensions.csproj file and run the following command in KUDU/SCM.
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:cf853765-793a-40cb-9435-d5d69d04e5b3" style="margin: 0px;padding: 0px;float: none">
<pre>dotnet build extensions.csproj -o bin --no-incremental --packages D:\home\.nuget</pre>
</div>
<h1>Declarative vs. Imperative Azure Functions</h1>
By default, Azure Functions use a declarative binding pattern that utilizes the function.json configuration file to define both input and output binding definitions.  For example, a default declarative binding pattern for an HTTP Triggered Azure Functions is similar to the following.  It includes the authLevel, the name of the input parameter passed into the Azure Function Run() method and the direction, etc.…
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:4b186aa7-12fc-4e46-b899-3d4532f31a83" style="margin: 0px;padding: 0px;float: none">
<pre>{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ],
  "disabled": false
}</pre>
</div>
With an HTTP Triggered Azure Function there is also a default output binding that returns the Task&lt;HttpResponseMessage&gt; to the client that triggered the Azure Function.  An Event Hub or Blob Trigger Azure Function, for example, do not have a default output binding.  You can add additional inputs or outputs for an Azure Function using the portal, Figure 2, or if you know the pattern you can update the json file directly,  Manually making the change to the json file via the portal can lead the issue I discussed <a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/08/07/why-does-my-azure-function-sometimes-stop-being-triggered/" rel="noopener">here</a>.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb3_thumb_thumb1.png"><img width="855" height="192" title="image_thumb3_thumb_thumb[1]" style="margin: 0px;border: 0px currentcolor" alt="image_thumb3_thumb_thumb[1]" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb3_thumb_thumb1_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 2, create an Azure Function App, configuring inputs and outputs</span></strong>

If there is a need to add an additional output binding for a Blob Storage account, then the function.json file would be updated to include this snippet.  It includes the type, the name of the output parameter that I can reference from the parameters in the Run() method, the direction and some others…
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:55f775e2-1cb5-4b03-9ca0-73605ecbb74e" style="margin: 0px;padding: 0px;float: none">
<pre>{
      "type": "blob",
      "name": "outputBlob",
      "path": "test/{rand-guid}",
      "connection": "AzureWebJobsDashboard",
      "direction": "out"
}</pre>
</div>
Now, onto imperative.  Think of the difference between Declarative and Imperative in the same way you think about design-time vs. runtime.  When you know from the beginning which combination of bindings the Azure Function requires, then create them declaratively, however, if, based on the processing of the input to the Azure Function, the output binding can have different endpoints, then imperative binding is necessary.

The way you imperatively (or at runtime) define bindings for an Azure Function is by passing the <a target="_blank" href="https://github.com/Azure/azure-webjobs-sdk/blob/master/src/Microsoft.Azure.WebJobs.Host/Bindings/Runtime/Binder.cs" rel="noopener">Binder</a> input parameter into the Run() method of the Azure Function, similar to the following.
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:bfa9a5bf-dd80-4ce7-bcca-d43aa4848abd" style="margin: 0px;padding: 0px;float: none">
<pre>Run(string input, Binder binder)</pre>
</div>
Then, within the Run() method, you can use the BindAsync&lt;T&gt;() method to dynamically create the output binding and utilize it.  For example, if instead of the outputBlob writing to path “test/” (which was declared declaratively) that can be identified at runtime, as shown in the following snippet.
<div id="scid:C89E2BDB-ADD3-4f7a-9810-1B7EACF446C1:006092e0-c2bb-48bb-b833-49ba2f3b1dfa" style="margin: 0px;padding: 0px;float: none">
<pre>public static async Task Run(string input, string name, Binder binder, TraceWriter log)
{
	string path = $"coolcontainer\{name}";
	var attributes = new Attribute[]
    {    
        new BlobAttribute(path),
        new StorageAccountAttribute("")
    };
	using (var writer = await binder.BindAsync(attributes))
    {
        writer.Write(input);
    }
}</pre>
</div>
<span>NOTE:</span> do not declaratively declare an output binding if you plan to define them imperatively in the code.

Here are more links that can add more details about runtime descriptions of out bound triggers.
<ul>
 	<li><a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#binding-at-runtime" rel="noopener">Triggers and Bindings - Binding at runtime</a></li>
 	<li><a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#binding-at-runtime" rel="noopener">C# class – Binding at runtime</a></li>
 	<li><a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-csharp#binding-at-runtime" rel="noopener">C# script – Binding at runtime</a></li>
</ul>
NOTE: I am actually leaning for towards using the client libraries for outbound triggers instead of the Binder approach.  Let’s see how this progresses over time.
<h1>Inbound vs. Outbound triggers</h1>
All Function Apps cannot create all outbound types of connections…

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb15_thumb_thumb1.png"><img width="855" height="231" title="image_thumb15_thumb_thumb[1]" style="margin: 0px;border: 0px currentcolor" alt="image_thumb15_thumb_thumb[1]" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb15_thumb_thumb1_thumb.png" border="0" /></a>
<h1>Dedicated vs. Consumption</h1>
The full description is <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale" rel="noopener">here</a> “Azure Functions scale and hosting” and will therefore not recover it.  NOTE:  In the article, dedicated is often referred to as App Service plan.  In summary, when you run an Azure Function App, which can contain many Azure Functions in the dedicated plan, it is not ‘really’ server-less because you are running it in an App Service Plan which you have already created, this is useful, however, when your Azure Function App needs more than 1.5GB of memory for example, you can also enable AlwaysOn and avoid any startup latencies.  Additionally, on a dedicated plan you are not limited to 5 or 10 minute execution times.  Running an Azure Function App in consumption mode is truly server-less, meaning, after a given amount of time where the your Azure Function is not used, the VM will be de-configured and returned to the pool of available resources.  When the Azure Function needs to run again, the VM will come back on-line and run.  You pay only for the time in which the code it executing.  So super awesome!
<h1>Getting Started</h1>
Create a Function App.  To complete the labs, you will need an Azure Function App.  It is assumed you already have an Azure Subscription and understand the concepts of Resource Groups, App Service Plans and the difference between a Dedicated versus Consumption based Azure Function App, oh…and the difference between an Azure Function App and an Azure Function would also be good to know…
<h3>Creating an Azure Function App</h3>
Login to the Azure portal and click the <strong>+Create a resource</strong> link on the top left of the page.  Search for ‘Function App’ and then select the Function App, as seen in Figure 3.  There is also some nice information <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-azure-function" rel="noopener">here</a> “Create your first function in the Azure portal”.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb1_thumb_thumb1.png"><img width="855" height="213" title="image_thumb1_thumb_thumb[1]" style="margin: 0px;border: 0px currentcolor" alt="image_thumb1_thumb_thumb[1]" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb1_thumb_thumb1_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 3, create an Azure Function App</span></strong>

Enter the required details for creating the Azure Function App, similar to that seen in Figure 4.

The <strong>App name</strong> must be unique as it is a global, internet accessible endpoint.

For these labs I recommend you create a new <strong>Resource Group</strong>.  I recommend that because once you are finished with these labs, you know which resources you created while working them and can delete them all once you finish.

Windows <strong>OS</strong>, and chose a Consumption Plan, <strong>Hosting Plan</strong> based Azure Function App for the labs but I cannot think of a reason why any of the labs wouldn’t work in dedicated or premium mode.

<a href="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb311_thumb1.png"><img width="338" height="830" title="image_thumb311_thumb[1]" style="border: 0px currentcolor" alt="image_thumb311_thumb[1]" src="https://msdnshared.blob.core.windows.net/media/2018/11/image_thumb311_thumb1_thumb.png" border="0" /></a>

<strong><span style="font-size: xx-small">Figure 4, create an Azure Function App</span></strong>

For <strong>Location</strong>, pick the one closest to you or, in a real situation, close to your customers/users. Make sure both <strong>Storage</strong> and <strong>Application</strong> <strong>Insights</strong> are in the same region as <strong>Location</strong>.  I have created one <strong>Storage</strong> account for all the Azure Function Apps, I have not seen any negatives of doing that.  Again, be sure to have the storage in the same region as the Azure Function App for performance reasons.  NOTE:  AFAIK there is no logic in the portal that puts a lock on or link between the Azure Function App and the selected storage account.  If you, for some reason, perhaps when you are going through your subscription resources, looking for resources to delete, you remove the storage account, you destroy all the Azure Function you have built, there is no recovery (<a target="_blank" href="https://blogs.msdn.microsoft.com/benjaminperkins/2018/08/09/where-are-my-azure-functions-dissappeared/" rel="noopener">*</a>).  This is why I have 1 storage account for all Azure Function Apps and I also give it a recognizable name…

Click the Create button to create the Azure Function App.  Done!  Once created, you are ready to begin the labs.]]></content:encoded>
    </item>
    <item>
      <title>The number 400</title>
      <link>https://docs.microsoft.com/archive/blogs/benjaminperkins/the-number-400</link>
      <pubDate>Fri, 05 Oct 2018 10:01:34 GMT</pubDate>
      <dc:creator><![CDATA[benjaminperkins]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/benjaminperkins/?p=28805</guid>
      <description><![CDATA[What is significant about the number 400?

 	400 is 20²
 	400 is divisible by: 1, 2, 4, 5, 8, 10,...]]></description>
      <content:encoded><![CDATA[What is significant about the number 400?
<ul>
 	<li>400 is 20²</li>
 	<li>400 is divisible by: 1, 2, 4, 5, 8, 10, 16, 20, 25, 40, 50, 80, 100, 200, 400</li>
 	<li>400 equals 2⁴ * 5² or ( 2*2*2*2*5*5)</li>
 	<li>400 is a self-number which are generated by this formula:  <img alt="C_k = 8 \cdot 10^{k - 1} + C_{k - 1} + 8" src="https://wikimedia.org/api/rest_v1/media/math/render/svg/16659e4a13a8e556981aad6f1f11f2a04efd4307" /></li>
 	<li>You can write 400 like this: four hundred, which is referred to as its Cardinal representation</li>
 	<li>400 comes after 399 and 401 follows 400</li>
 	<li>400² is 160000</li>
 	<li>An HTTP Status code of 400 means, Bad Request, which could not be understood by the server due to a malformed syntax.</li>
 	<li>6 minutes and 40 seconds is equal to 400 seconds</li>
 	<li>400 is a Harshad number</li>
 	<li>400 can be represented in Greek by Υ´</li>
 	<li>The scientific notation of 400 is 4 * 10²</li>
 	<li>There was an Atari 400 computer, my first computer was an Atari 1200XL</li>
 	<li>400 in binary is 110010000</li>
 	<li>400 is represented in Roman number CD</li>
 	<li>There are 400 days in a Gregorian calendar</li>
 	<li>400 in hexadecimal is 0x190</li>
 	<li>The Sun is 400 times larger than the moon and 400 times further away from the Earth</li>
 	<li>Counting to 400 will take about 3 minutes</li>
 	<li>There is a Forbes 400 list of richest people which I am not on</li>
 	<li>There are 400 grades in a circle</li>
</ul>
Lastly, <strong>the number 400 is the number of articles I have written and posted to the MSDN platform.</strong>  This is my 400th.]]></content:encoded>
    </item>
  </channel>
</rss>