Implementar prácticas recomendadas para  Azure Functions

En este capítulo, aprenderás algunas de las prácticas recomendadas para trabajar con Azure Functions, entre ellas:

  • Agregar varios mensajes a una cola mediante la función IAsyncCollector
  • Implementar aplicaciones defensivas con Azure Functions  y desencadenadores de cola
  • Administrar entradas masivas mediante Event Hubs para IoT y otros escenarios similares
  • Evitar arranques en frío activando la aplicación periódicamente
  • Habilitar autorización para aplicaciones de función
  • Controlar el acceso a Azure Functions mediante claves de función
  • Proteger Azure Functions mediante Azure Active Directory
  • Configurar la limitación de Azure Functions mediante API Management
  • Acceder de forma segura a SQL Database desde Azure Functions mediante Managed Service Identity
  • Código compartido en Azure Functions mediante bibliotecas de clases
  • Usar clases fuertemente tipadas en Azure Functions

Agregar varios mensajes a una cola mediante la función IAsyncCollector

En el primer capítulo, has aprendido a crear un mensaje de cola para cada solicitud procedente de la solicitud HTTP. Ahora supongamos que cada usuario va  a registrar su dispositivo mediante aplicaciones cliente (como aplicaciones de escritorio, aplicaciones móviles o cualquier sitio web de cliente) que pueden enviar varios registros en una sola solicitud. En estos casos, la aplicación de back-end debe ser lo suficientemente inteligente como para manejar la carga que le llega; debe existir un mecanismo que permita crear varios mensajes de cola a la vez y de forma asincrónica. Aprenderás a crear varios mensajes de cola mediante la  interfaz IAsyncCollector.

A continuación, se muestra un diagrama que representa el flujo de datos desde diferentes aplicaciones cliente a la API web de back-end:

En esta receta, vamos a simular las solicitudes mediante Postman, que enviará la solicitud a la API web de back-end (HTTPTrigger), que puede crear todos los mensajes de cola de una sola vez.

Preparación

Estos son los pasos necesarios:

  1. Crea una cuenta de almacenamiento mediante Azure Portal si aún  no lo has hecho
  2. Instala el explorador de Microsoft Azure Storage desde http:// storageexplorer.com/ si aún no lo has instalado

Cómo hacerlo…

Sigue estos pasos:

  1. Crea un nuevo desencadenador de HTTP denominado

BulkDeviceRegistrations y establece el nivel de autorización en Anónimo.

  • Reemplaza el código predeterminado por el siguiente código y haz clic en el botón Guardar para guardar los cambios. El código siguiente espera una matriz JSON como un parámetro de entrada con un atributo denominado «devices». Si se encuentra, se repetirá a través de los elementos de la matriz y, a continuación, los mostrará en los registros. Más adelante, modificaremos el programa para insertar de forma masiva los elementos de la matriz en el mensaje de cola:

#r «Newtonsoft.Json» using System.Net; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives;

using Newtonsoft.Json;

public static async Task<IActionResult> Run(HttpRequest req,

ILogger log )

{

log.LogInformation(«C# HTTP trigger function processed a

request.»); string requestBody = await new StreamReader(req.Body). ReadToEndAsync();

dynamic data = JsonConvert.DeserializeObject(requestBody);

string Device = string.Empty;

for(int nIndex=0;nIndex<data.devices.Count;nIndex++)

{

Device = Convert.ToString(data.devices[nIndex]); log.LogInformation(«devices data» + Device);

}

return (ActionResult)new OkObjectResult(«Program has been executed

Successfully.»);

}

  • El siguiente paso es crear un enlace de salida de Azure Queue Storage. Haz clic en el botón Guardar, ve a la pestaña Integrar y agrega un nuevo enlace de salida de Azure Queue Storage. A continuación, haz clic en el botón Seleccionar y proporciona el nombre de la cola y otros parámetros.
  • Haz clic en el botón Guardar y ve al editor de código de la Azure Function. Agrega el código adicional necesario para el enlace de salida con la cola para guardar los mensajes, como se muestra en el código siguiente. Realiza los cambios resaltados en el editor de código y haz clic en el botón Guardar para guardar los cambios:

public static async Task<IActionResult> Run(HttpRequest req,

ILogger log,

IAsyncCollector<string> DeviceQueue )

{ …. …. for(int nIndex=0;nIndex<data.devices.Count;nIndex++)

{

 Device = Convert.ToString(data.devices[nIndex]);

 DeviceQueue.AddAsync(Device); } ….

….

5. Vamos a ejecutar la función desde la pestaña Prueba del portal con el siguiente JSON de solicitud de entrada:

        {         «devices»:

           [

             {

               «type»: «laptop»,

               «brand»:»lenovo»,

               «model»:»T440″

             },

             {

                «type»: «mobile»,

                «brand»:»Mi»,

                «model»:»Red Mi 4″

             }

           ]

        }

6. Haz clic en el botón Ejecutar para probar la funcionalidad. Ahora abre el explorador de Azure Storage y ve a la cola denominada «devicequeue». Como se muestra en la siguiente captura de pantalla, deben aparecer  dos registros:

Cómo funciona…

Hemos creado una nueva función HTTP que tiene un parámetro del tipo IAsyncCollector<string>, que se puede utilizar para almacenar varios mensajes en un servicio de cola a la vez y de forma asincrónica. Este procedimiento para almacenar varios elementos de forma asincrónica reducirá la carga en las instancias.

Por último, hemos probado la invocación del desencadenador de HTTP desde Azure Portal y hemos visto asimismo que los mensajes de la cola se ha podido agregar mediante el explorador de Azure Storage.

Y eso no es todo…

También puedes utilizar la interfaz ICollector, en lugar de IAsyncCollector,  si deseas almacenar varios mensajes de forma asincrónica.

Ten en cuenta que es posible que tengas que instalar extensiones de Azure Storage para agregar enlaces de salida si todavía no lo has hecho. En el runtime de Azure Functions v2, es obligatorio agregar extensiones a cada uno de los servicios (almacenamiento, en este caso).

Implementar aplicaciones defensivas con Azure Functions y desencadenadores  de cola

Para muchas aplicaciones, incluso después de realizar varias pruebas de diferentes entornos, podrían seguir existiendo motivos de posibles errores en la aplicación. Los desarrolladores y arquitectos no pueden predecir todas las entradas imprevistas durante la vida útil de una aplicación utilizada por usuarios profesionales o usuarios generales finales. Por lo tanto, es recomendable asegurarse de que la aplicación te notifica cualquier error o problema imprevisto en las aplicaciones.

En esta receta, aprenderás cómo nos ayuda Azure Functions a controlar este tipo de problemas con un código mínimo.

Preparación

Estos son los pasos necesarios:

  1. Crear una cuenta de almacenamiento mediante Azure Portal si aún  no lo has hecho
  2. Instalar el explorador de Azure Storage desde http://storageexplorer. com/ si aún no lo has instalado

Cómo hacerlo…

En esta receta, haremos lo siguiente:

  • Desarrollar una aplicación de consola con C# que se conecte a la cuenta de almacenamiento y cree mensajes de cola en la cola denominada myqueuemessages
  • Crear un desencadenador de cola de la Azure Function denominada ProcessData que se active cada vez que se agregue un mensaje nuevo a la cola denominada myqueuemessages

CreateQueueMessage: aplicación de consola de C#

Sigue estos pasos:

  1. Crea una nueva aplicación de consola con el lenguaje C# de .NET Core y crea una clave de configuración de la aplicación denominada StorageConnectionString con la cadena de conexión de la cuenta de almacenamiento. Puedes obtener la cadena de conexión de la hoja Claves de acceso de la cuenta de almacenamiento, tal como se muestra:
  • Instala los paquetes NuGet de Configuración y Almacenamiento de cola utilizando los siguientes comandos:

      Install-Package Microsoft.Azure.Storage.Queue  

      Install-Package System.Configuration.ConfigurationManager

  • Agrega los siguientes espacios de nombres:

        using Microsoft.WindowsAzure.Storage;         using Microsoft.WindowsAzure.Storage.Queue;

        using System.Configuration;

  • Agrega la siguiente función a la aplicación de consola y llámala desde el método Main. La función CreateQueueMessages crea 100 mensajes con el índice como contenido de cada mensaje:

        static void CreateQueueMessages()

        {

           CloudStorageAccount storageAccount = 

            CloudStorageAccount.Parse(ConfigurationManager.

AppSettings

            [«StorageConnectionString»]);

           CloudQueueClient queueclient =              storageAccount.CreateCloudQueueClient();

           CloudQueue queue = queueclient.GetQueueReference

            («myqueuemessages»);            queue.CreateIfNotExists();

           CloudQueueMessage message = null;

           for(int nQueueMessageIndex = 0; nQueueMessageIndex <=

100; 

            nQueueMessageIndex++)

           {

              message = new CloudQueueMessage(Convert.ToString

               (nQueueMessageIndex));               queue.AddMessage(message);

              Console.WriteLine(nQueueMessageIndex);

           }

        }

Desarrollar la Azure Function: desencadenador  de cola

Sigue estos pasos:

  1. Crea una función de Azure nueva denominada ProcessData mediante el desencadenador de cola y configura la cola myqueuemessages. Así es como debe mostrarse la pestaña Integrar una vez creada la función:
  • Reemplaza el código predeterminado por el código siguiente:

        using System;

        public static void Run(string myQueueItem, 

         ILogger log)

        {

           if(Convert.ToInt32(myQueueItem)>50)

           {

              throw new Exception(myQueueItem);

           }            else            {

              log.LogInformation($»C# Queue trigger function 

               processed: {myQueueItem}»);

           }

        }

El desencadenador de cola anterior registra un mensaje con el contenido de la cola (es solo un índice numérico) para los primeros 50 mensajes y, a continuación, genera una excepción para todos los mensajes cuyo contenido es mayor que 50.

Ejecutar pruebas mediante la aplicación de consola

Sigue estos pasos:

  1. Vamos a ejecutar la aplicación de consola. Para ello, pulsa Ctrl + F5, ve al explorador de Azure Storage y revisa el contenido de la cola.
  2. En apenas unos instantes, deberían mostrarse los mensajes de la cola myqueuemessages. Actualmente, tanto Azure Portal como el explorador de Azure Storage muestran los primeros 32 mensajes. Debes usar el Storage SDK de C# para ver todos los mensajes de la cola.

No te sorprendas si observas que los mensajes de la myqueuemessage están desapareciendo. Una vez leído correctamente un mensaje, este se elimina de la cola.

  • Como se muestra aquí, también debería aparecer una cola nueva denominada myqueuemessages-poison (<OriginalQueuename>-Poison) con los otros 50 mensajes de la cola en ella. El runtime de Azure Function se encargará de crear automáticamente una nueva cola y agregar los mensajes que Azure Functions no haya leído correctamente:

Hemos creado una aplicación de consola que crea mensajes en Azure Queue Storage y también hemos desarrollado un desencadenador de cola que es capaz de leer los mensajes de la cola. Como parte de la simulación de un error imprevisto, hemos hecho que se genere un error si el valor del contenido del mensaje de cola es mayor que 50.

Azure Functions se encargará de crear una nueva cola con el nombre <OriginalQueueName>-Poison e insertará todos los mensajes sin procesar en la nueva cola. Con esta nueva cola de daños, los desarrolladores pueden revisar el contenido de los mensajes y tomar las medidas necesarias para corregir errores  en las aplicaciones.

El runtime de Azure Function se encargará de eliminar el mensaje de cola una vez que se haya completado correctamente la ejecución de dicha función. Si hay algún problema en la ejecución de la Azure Function, crea automáticamente una nueva cola de daños y agrega los mensajes procesados a la nueva cola.

Y eso no es todo…

Antes de insertar un mensaje de cola en la cola de daños, el runtime de Azure Function intenta seleccionar el mensaje y procesarlo cinco veces. Puedes obtener información sobre cómo funciona este proceso si agregas un nuevo parámetro dequecount del tipo int al método Run y registras su valor.

Administrar entradas masivas  mediante Event Hubs para IoT y otros escenarios similares

En muchos casos, es posible que necesites controlar grandes cantidades de datos entrantes. Los datos entrantes pueden proceder de sensores y datos de telemetría, y pueden ser simplemente los datos enviados por dispositivos con Fitbit. En estas situaciones, necesitamos contar con una solución fiable que sea capaz de administrar cantidades masivas de datos. Azure Event Hubs es una de las soluciones que proporciona Azure. En esta receta, aprenderás cómo integrar Event Hubs  y Azure Functions.

Preparación

Sigue estos pasos:

  1. Crea un espacio de nombres de Event Hubs. Para ello, ve al Internet de las cosas y selecciona Event Hubs.
  2. Una vez creado el espacio de nombres de Event Hubs, ve la pestaña Información general y haz clic en el icono Centro de eventos para crear un Centro de eventos nuevo.
  3. De forma predeterminada, se creará un Grupo de consumidores denominado $Default, que es el que vamos a utilizar en esta receta.

Cómo hacerlo…

En esta receta, vamos a seguir estos pasos:

  • Crear un desencadenador de centro de eventos de la Azure Function
  • Desarrollar una aplicación de consola que simule los datos del Internet de las cosas (IoT)

Crear un desencadenador de centro de eventos de la Azure Function

Sigue estos pasos:

  1. Para crear una nueva función de Azure, selecciona Desencadenador de centro de eventos en la lista de plantillas.
  2. Una vez seleccionada la plantilla, es posible que tengas que instalar las extensiones. A continuación, deberás proporcionar el nombre del centro de eventos, capturemessage. Si aún no has configurado ninguna conexión, haz clic en el botón Nueva.
  3. Al hacer clic en el botón Nueva, se abrirá una ventana emergente de Conexión en la que puedes seleccionar el Centro de eventos y otros datos. Selecciona los datos solicitados y haz clic en el botón Seleccionar, como se muestra en la siguiente captura de pantalla:
  • El paso anterior rellenará el menú desplegable de Conexión del centro de eventos. Por último, haz clic en Crear para crear la función.

Desarrollar una aplicación de consola que simule los datos de IoT

Sigue estos pasos:

  1. Crea una nueva aplicación de consola que se encargue de enviar eventos al centro de eventos. Yo la he nombrado EventHubApp.
  2. Ejecuta los siguientes comandos en el administrador de paquetes de NuGet para instalar las bibliotecas necesarias e interactuar con Azure Event Hubs:

      Install-Package Microsoft.Azure.EventHubs       Install-Package Newtonsoft.Json

  • Agrega los siguientes espacios de nombres y una referencia a System. Configuration.dll:

        using Microsoft.Azure.EventHubs;          using System.Configuration;    

  • Agrega la cadena de conexión a App.config, que se utiliza para conectar el centro de eventos. Este es el código para App.config. Para obtener la cadena de conexión, haz clic en el enlace ConnectionStrings de la pestaña Información general del espacio de nombres del centro de eventos:

        <?xml version=»1.0″ encoding=»utf-8″ ?>

        <configuration>

        <startup> 

        <supportedRuntime version=»v4.0″           sku=».NETFramework,Version=v4.6.1″ />

        </startup>

        <appSettings>

        <add key=»EventHubConnection» 

          value=»Endpoint=sb://<event hub namespace             here>.servicebus.windows.net/;Entitypath=<Event

Hubname>;           SharedAccessKeyName= RootManageSharedAccessKey;

           SharedAccessKey=<Key here>»/>

        </appSettings>

        </configuration>

5. Crea un nuevo archivo de clase de C# y coloca el código siguiente en el nuevo archivo de clase:

        using System;         using System.Text;         using Microsoft.Azure.EventHubs;         using System.Configuration;         using System.Threading.Tasks;

        namespace EventHubApp

        {

           class EventHubHelper

           {

              static EventHubClient eventHubClient = null;               public static async Task GenerateEventHubMessages()

              {

                 EventHubsConnectionStringBuilder conBuilder = new

                  EventHubsConnectionStringBuilder

                  (ConfigurationManager.AppSettings

                  [«EventHubConnection»].ToString());

                 eventHubClient = 

                  EventHubClient.CreateFromConnectionString

                  (conBuilder.ToString());                  string strMessage = string.Empty;                  for (int nEventIndex = 0; nEventIndex <= 100; 

                  nEventIndex++)

                 {

                    strMessage = Convert.ToString(nEventIndex);                     await eventHubClient.SendAsync(new EventData

                     (Encoding.UTF8.GetBytes(strMessage)));

                    Console.WriteLine(strMessage);

                 }

                 await eventHubClient.CloseAsync();

              }

           }

        }

  • En tu función principal, coloca el siguiente código, que invoca el método para enviar el mensaje:

        namespace EventHubApp

        {

           class Program

           {

              static void Main(string[] args)

              {

                 EventHubHelper.GenerateEventHubMessages().Wait();

              } 

           }

        }

  • Ahora ejecuta la aplicación pulsando Ctrl + F5. Debería aparecer algo similar a lo que se muestra aquí:
  • Mientras la consola imprime los números, puedes ir a la Azure Function para comprobar si el centro de eventos se activa automáticamente y registra los números que se están enviando al centro de eventos.

Evitar arranques en frío activando la aplicación periódicamente

Por ahora, ya sabes que puedes crear funciones de Azure en los dos planes de hosting siguientes:

  • Plan de App Service
    • Plan de consumo

Solo podrás obtener todas las ventajas de la arquitectura sin servidor si creas la Function App mediante el plan de consumo. Sin embargo, uno de los problemas del que han informado los desarrolladores en cuanto al uso del plan de consumo es lo que se conoce como arranque en frío, que consiste en poner en marcha una función de Azure para atender las solicitudes sin que se hayan recibido solicitudes desde hace tiempo. Puedes obtener más información sobre este tema en  https://blogs.msdn.microsoft.com/appserviceteam/2018/02/07/ understanding-serverless-cold-start/.

En esta receta, aprenderemos una técnica que se podría utilizar para  mantener siempre activa la instancia, de tal modo que todas las solicitudes se atiendan correctamente.

El plan de App Service es un plan de hosting dedicado en el que las instancias están reservadas para ti y pueden estar siempre activas, aunque no se reciban solicitudes durante cierto tiempo.

Preparación

Para completar esta receta, debemos tener una aplicación de función con lo siguiente:

  • Un desencadenador de HTTP denominado HttpALive
  • Un desencadenador de temporizador denominado KeepFunctionAppWarm que se ejecuta cada 5 minutos y realiza una solicitud HTTP al desencadenador de HTTP HttpALive

Si has entendido claramente en qué consiste un arranque en frío, ya debes tener igualmente claro que no habrá ningún problema si la aplicación ha tenido un tráfico regular durante el día. Por lo tanto, si podemos garantizar que la aplicación tiene tráfico durante todo el día, la instancia de la Azure Function no se desaprovisionará y, por lo tanto, tampoco debe haber problema ninguno con el plan de consumo.

Cómo hacerlo…

En esta receta, vamos a crear un desencadenador de temporizador que simulará el tráfico al desencadenador de HTTP, lo que hará que la Function App esté permanentemente activa y las instancias sin servidor estén siempre en  estado aprovisionado.

Crear un desencadenador de HTTP

Crea un desencadenador de HTTP nuevo y reemplaza el siguiente código, que tan solo imprime un mensaje cuando se ejecuta:

using System.Net; using Microsoft.AspNetCore.Mvc;

public static async Task<IActionResult> Run(HttpRequest req, ILogger

log) {

return (ActionResult)new OkObjectResult($»Hello User! Thanks for

keeping me Warm»);

}

Crear un desencadenador de temporizador

Sigue estos pasos:

  1. Haz clic en el icono +, busca el temporizador y haz clic en el botón Desencadenador de temporizador.
  2. En la ventana emergente Nueva función, proporciona los datos necesarios. En este caso, la Programación es una expresión CRON que garantiza que el desencadenador de temporizador se active automáticamente cada 5 minutos:
  • Pega el siguiente código en el editor de código y guarda los cambios. El código siguiente simula el tráfico generando solicitudes HTTP mediante programación. Asegúrate de reemplazar <<FunctionAppName>> con el nombre real de la Function App:

using System;

public async static void Run(TimerInfo myTimer, ILogger log)

{

using (var httpClient = new HttpClient())

{

var response = await httpClient.GetAsync(«https://<FunctionAppNa

me>>.azurewebsites.net/api/HttpALive»);

}

}

Y eso no es todo…

Si experimentas un poco con Azure Functions, podrás observar que los tiempos de arranque en frío para Azure Functions que tienen C# como lenguaje son de apenas unos segundos. Sin embargo, si trabajas con Azure Functions que utilizan JavaScript (como Node.js) como lenguaje, el tiempo de arranque en frío será mayor, dado que el runtime tiene que descargar todos los paquetes de NPM que son dependencias de la aplicación. Para estos casos hay una función, denominada Ejecutar desde el paquete, que resulta muy útil. Vamos a aprender cómo implementar esto en el próximo capítulo.

Consulta también

Consulta la receta Implementar Azure Functions mediante Ejecutar desde el paquete del capítulo 10, Configurar aplicaciones sin servidor en el entorno de producción.

Habilitar autorización para aplicaciones de función

Si la API web (desencadenador de HTTP) se está utilizando en varias aplicaciones cliente y deseas proporcionar acceso únicamente a las aplicaciones previstas  y autorizadas, debes implementar la autorización para restringir el acceso a la  Azure Function.

Preparación

Supongo que ya sabes cómo crear una función de desencadenador de HTTP.

Puedes descargar la herramienta Postman de https://www.getpostman.com/. La herramienta Postman se utiliza para enviar solicitudes HTTP. También puedes utilizar cualquier herramienta o aplicación que permita enviar solicitudes  y encabezados HTTP.

Cómo hacerlo…

Sigue estos pasos:

  1. Crea una nueva función de desencadenador de HTTP (o abre una función HTTP existente). Asegúrate de que al crear la función, seleccionas la opción Función en el menú desplegable de nivel de Autorización.

Si deseas elegir una función de desencadenador de HTTP existente que hayamos creado en una de las recetas anteriores, haz clic en la pestaña Integrar, cambia el nivel de Autorización a Función y haz clic en el botón Guardar para guardar  los cambios.

  • En la pestaña Editor de código, obtén la dirección URL de la función a través del enlace Obtener dirección URL de la función disponible en la esquina derecha del editor de código en el archivo run.csx.
  • Ve a Postman y pega la dirección URL de la función:
  • Observa que la dirección URL tiene las siguientes cadenas de consulta:

° code: esta es la cadena de consulta predeterminada prevista por el runtime de la función y valida los derechos de acceso de la función. La funcionalidad de validación se activa automáticamente sin necesidad de que el desarrollador escriba el código. Para que suceda todo esto tan solo hay que establecer el nivel de Autorización  en Función.

° name: esta es una cadena de consulta requerida por la función de disparador HTTP.

  • Vamos a quitar la cadena de consulta de código de la dirección URL  en Postman e intentar realizar una solicitud. Se mostrará un error  401: No autorizado.

Cómo funciona…

Al realizar una solicitud a través de Postman o de cualquier otra herramienta  o aplicación que pueda enviar solicitudes HTTP, la aplicación web de Azure App Service subyacente recibirá la solicitud (ten en cuenta que Azure Functions se basa en App Services), que primero comprueba si está presente el código del nombre de encabezado en la colección de cadenas de consulta o en el cuerpo de la solicitud. Si lo encuentra, valida el valor de la cadena de consulta de código con las claves de función. Si es válido, autoriza la solicitud y permite que el runtime la procese. De lo contrario, se genera un error con el mensaje 401: No autorizado.

Y eso no es todo…

Ten en cuenta que la clave de seguridad (parámetro de cadena de consulta con el nombre code) del ejemplo anterior se usa solo con fines de demostración. En escenarios de producción, en lugar de pasar la clave como un parámetro de cadena de consulta (el parámetro code), debes agregar la clave x-functions-key como encabezado HTTP, como se muestra en la siguiente captura de pantalla:

Controlar el acceso a Azure Functions mediante claves de función

Ahora ya sabes cómo habilitar la autorización de un desencadenador de HTTP individual mediante la configuración del campo Nivel anónimo a través de la función value en la pestaña Integrar de la función de desencadenador HTTP. Funciona bien si tienes solamente una función de Azure como API web de back-end para una de tus aplicaciones y no deseas restringir el acceso al público.

Sin embargo, en las aplicaciones de nivel empresarial, terminarás desarrollando varias Azure Functions en varias aplicaciones de función. En esos casos, debes disponer de un nivel de acceso específico y perfectamente delimitado a la Azure Function para tus propias aplicaciones o para aplicaciones de terceros que integren tus API en sus aplicaciones.

En esta receta, aprenderás a trabajar con claves de función dentro  de Azure Functions.

Cómo hacerlo…

Azure es compatible con las siguientes claves, que se pueden utilizar para controlar el acceso a Azure Functions:

  • Claves de función: se pueden utilizar para otorgar permisos de autorización a una función determinada. Estas claves son específicas de la función con la que están asociadas.
  • Claves de host: podemos usarlas para controlar la autorización de todas las funciones dentro de una aplicación de función de Azure.

Configurar la clave de función para cada aplicación

Si vas a desarrollar una API con Azure Functions que pueden utilizar varias aplicaciones, es recomendable tener una clave de función diferente para cada aplicación cliente que vaya a usar las funciones.

Ve a la pestaña Administrar de Azure Functions para ver y administrar todas las claves relacionadas con la función.

De forma predeterminada, se genera una clave con el nombre predeterminado.  Si deseas generar una clave nueva, haz clic en el botón Agregar nueva clave  de función.

Conforme a la instrucción anterior, he creado las claves para las siguientes aplicaciones:

  • WebApplication: el nombre de clave WebApplication está configurado para utilizarse en el sitio web que utiliza la Azure Function.
  • MobileApplication: el nombre de clave MobileApplication está configurado para utilizarse en la aplicación móvil que utiliza la  Azure Function.

Del mismo modo, puedes crear diferentes claves para cualquier otra aplicación  (por ejemplo, una aplicación de IoT) en función de tus requisitos.

Al contar con diferentes claves para la misma función podrás tener control sobre los permisos de acceso de diferentes aplicaciones para el uso de las funciones. Por ejemplo, si deseas revocar los permisos solo a una aplicación, y no a todas ellas, tan solo tendrás que eliminar (o revocar) esa clave. De esa manera, no afectará a otras aplicaciones que estén utilizando la misma función.

Este es el inconveniente de las claves de función. Si vas a desarrollar una aplicación en la que necesites tener varias funciones y cada función la van a utilizar distintas aplicaciones, tendrás que disponer de muchas claves. Administrar estas claves  y documentarlas sería una pesadilla. En tal caso, puedes optar por las claves de host, de las que vamos a hablar a continuación.

Configurar una clave de host para todas las funciones en una sola aplicación de función

Tener diferentes claves para diferentes funciones es un práctica recomendada si tienes varias funciones que utilizan distintas aplicaciones. Sin embargo, la situación podría empeorar si hay muchas funciones y muchas aplicaciones cliente que hacen uso de tus API. La administración de las claves de función en estas aplicaciones empresariales de gran tamaño con enormes bases de clientes sería realmente tediosa. Para simplificar todo, puedes segregar todas las funciones relacionadas en una sola aplicación de función y configurar la autorización para cada aplicación de función en lugar de hacerlo para cada función individual. Puedes configurar la autorización para una aplicación de función mediante claves de host.

Estos son los dos tipos diferentes de claves de host disponibles:

  • Claves de host normales
  • Clave maestra

Crea dos aplicaciones de desencadenador de HTTP, como se muestra en la siguiente captura de pantalla:

Ve a la pestaña Administrar de ambas aplicaciones, como se muestra en las siguientes capturas de pantalla. Observarás que tanto la clave maestra como las claves de host son las mismas en las dos aplicaciones:

  • Esta es la pestaña de administración de MyApp1:
  • Esta es la pestaña de administración de MyApp2:

Y eso no es todo…

Si crees que la clave ha sido atacada, puedes volver a generarla en cualquier momento a través del botón Renovar. Ten en cuenta que cuando se renueva una clave, todas las aplicaciones que acceden a la función ya no funcionarán y se generará un error con el código de estado 401: No autorizado.

Puedes eliminar o revocar la clave si ya no se utiliza en ninguna de las aplicaciones.

A continuación, se muestra una tabla con más información sobre las claves:

Tipo de clave¿Cuándo debo usarla?¿Es revocable (se puede borrar)?¿Es renovable?Comentarios
Clave maestraSi el nivel de Autorización es AdministradorNoPuedes utilizar una clave maestra para cualquier función dentro de la Function App, independientemente del nivel de autorización configurado.
Clave de hostSi el nivel de Autorización es FunciónPuedes utilizar la clave de host para todas las funciones dentro de la Function App.
Clave de funciónSi el nivel de Autorización es FunciónPuedes utilizar la clave de función solo para una función determinada.

Microsoft no recomienda compartir la clave maestra, ya que también la usan las API del runtime. Debes tener gran precaución con las claves maestras.

Proteger Azure Functions mediante Azure Active Directory

En la receta anterior, hemos aprendido a habilitar la seguridad en función de las aplicaciones cliente que acceden a Azure Functions. Sin embargo, si el requisito es autenticar a los usuarios finales que acceden a las funciones en Azure Active Directory (AD), Azure Functions proporciona una forma sencilla de configurar este método conocido como EasyAuth.

Gracias a Azure App Service, desde el que se hereda la función EasyAuth, podemos hacer lo que sea necesario sin escribir una sola línea de código.

Preparación

En esta receta, para simplificar el procedimiento, vamos a utilizar el AD predeterminado que se crea durante la creación de una cuenta de Azure. Sin embargo, en los escenarios de producción en tiempo real, ya tendrías un AD existente que tendría que integrarse. Es recomendable leer este artículo: 

https://docs.microsoft.com/azure/active-directory-b2c/activedirectory-b2c-tutorials-web-app.

Cómo hacerlo…

En esta receta, haremos lo siguiente:

  • Configurar Azure AD para la Function App
  • Registrar la aplicación cliente en Azure AD
  • Conceder a la aplicación cliente acceso a la aplicación de back-end
  • Probar la funcionalidad de autenticación mediante un token JWT

Configurar Azure AD para la Function App

Sigue estos pasos:

  1. Ve a la sección Características de la plataforma de Azure Functions.
  2. En la hoja Autenticación/Autorización, realiza los pasos siguientes para habilitar la autenticación de AD:
    1. Haz clic en el botón Activada para habilitar la autenticación.
    1. Selecciona la opción Iniciar sesión a través de la opción de menú Azure Active Directory.
    1. Haz clic en el botón Sin configurar para comenzar a configurar  las opciones.
  3. El siguiente paso es elegir un registro existente o crear uno nuevo para la aplicación cliente a la que deseamos conceder acceso. Para ello, pulsa el botón Rápida del campo Modo de administración. Además, yo opté por crear uno nuevo e introduje AzureFunctionCookbookV2 como nombre para el registro de mi aplicación. Haz clic en Aceptar para guardar las configuraciones y se abrirá la siguiente pantalla.
  4. Obtén el Id. de la aplicación, tal como se muestra. Lo vamos a utilizar durante nuestra prueba en unos instantes:

Eso es todo. Sin escribir una sola línea de código, hemos terminado con la configuración de una instancia de Azure AD que funciona como capa de seguridad y permite el acceso solo a los usuarios autenticados. Es decir, hemos habilitado OAuth para nuestra Function App de back-end con Azure AD. Vamos a probarlo rápidamente accediendo a cualquiera de los desencadenadores de HTTP que tienes en la Function App. Para realizar esta prueba he utilizado Postman. Como es de esperar, aparecerá un mensaje de error en el que se te pedirá que inicies sesión.

Con las configuraciones actuales, ninguna de las aplicaciones cliente externas podrá acceder a nuestra API de back-end. Para otorgar el acceso necesario, tienes que seguir estos pasos:

Registra todas las aplicaciones cliente en Azure AD (para nuestro ejemplo, vamos  a realizar un registro para la aplicación Postman).

Concede acceso a la aplicación de back-end.

Registrar la aplicación cliente en Azure AD

Sigue estos pasos:

  1. Abre Azure AD a través del botón Azure Active Directory, tal como se muestra. Si no aparece en la lista de favoritos, lo puedes buscar en la hoja Todos los servicios, que también aparece resaltada en la siguiente  captura de pantalla:
  • En el menú AD, haz clic en Registros de aplicaciones y, a continuación, haz clic en el botón de registro Nueva aplicación.
  • Rellena los campos de la siguiente manera y haz clic en el botón Crear para completar el registro de la aplicación Postman. Dado que nuestra aplicación cliente es Postman, la URL de inicio de sesión no es importante, por lo que podemos utilizar http://localhost para nuestro ejemplo:
  • En unos instantes, se creará la aplicación y se abrirá la siguiente pantalla. Obtén el Id. de la aplicación y guárdalo en el bloc de notas. Lo vamos  a utilizar en los pasos siguientes. Haz clic en el botón Configuración:
  • En la hoja Configuración, haz clic en el elemento de menú Claves para generar una clave, que vamos a pasar desde Postman. Para generar la clave, primero tenemos que proporcionar una Descripción y la Duración del tiempo de vigencia tras el que debe expirar la clave. Proporciona los datos como se muestran en la siguiente captura de pantalla y haz clic en el botón Guardar. La clave real se muestra en el campo de valor solo una vez inmediatamente después de hacer clic en el botón Guardar, así que asegúrate de copiarlo y almacenarlo en un lugar seguro. Vamos a utilizarla en breve:

Conceder a la aplicación cliente acceso a la aplicación de back-end

Una vez registrada la aplicación cliente, tenemos que proporcionarle el acceso  a nuestra aplicación de back-end. En esta sección, vamos a aprender a configurarla:

  1. Haz clic en la pestaña Permisos necesarios y en el botón Agregar, de tal forma que se mostrará la hoja Agregar acceso de API, donde debes seleccionar la API necesaria (en nuestro caso, es la API de back-end  de Azure Functions).
  2. En la hoja Agregar acceso de API, haz clic en el botón Seleccionar una API; inicialmente, se mostrarán las API predeterminadas. Tienes que buscar la aplicación de back-end con el nombre que hayas proporcionado (en mi caso, fue AzureFunctionCookBookV2). Selecciona la aplicación de back-end y haz clic en el botón Seleccionar.
  3. El siguiente paso es proporcionar los permisos reales. Haz clic en la hoja Seleccionar permisos y comprueba el <Backend App name> de acceso  y, a continuación, haz clic en el botón Hecho.
  4. Asegúrate de que aparece la siguiente pantalla. También puedes hacer clic en el botón Conceder permiso para aplicar los cambios:

Probar la funcionalidad de autenticación mediante un token JWT

Debes tener preparado lo siguiente para probar la funcionalidad mediante Postman:

  1. Punto de conexión de token de OAuth 2.0. Para ello, ve a la pestaña Puntos de conexión de Azure AD y obtén la dirección URL:

                       °    Tipo de concesión: un valor de client_credentials codificado.

°     Id. de cliente de la aplicación cliente: lo anotaste en el cuarto paso de la sección Registrar la aplicación cliente en Azure AD.

°     Clave que generaste para la aplicación cliente: la anotaste en el quinto paso de la sección Registrar la aplicación cliente en Azure AD.

°     Recurso: recurso al que necesitamos acceder. Es el Id. de cliente de la aplicación de back-end; lo anotaste en el cuarto paso de la sección Configurar Azure AD para la Function App.

  • Una vez que dispongas de toda esa información, debes pasar todos los parámetros y realizar una llamada a un inquilino de Azure AD, que devuelve el token de portador de la siguiente manera:
  • El siguiente y último paso es realizar una llamada al back-end real  (el desencadenador de HTTP de la Azure Function) pasando el token de portador de JWT (access_token) que copiamos de la pantalla anterior:
  • Como se muestra en esta captura de pantalla, agrega un encabezado de Autorización y pega el token de JWT. No olvides proporcionar la palabra portadora de texto.

Configurar la limitación de Azure Functions mediante API Management

En capítulos anteriores, ya hemos aprendido que podemos utilizar los desencadenadores de HTTP de Azure Functions como API Web de back-end. Si deseas restringir el número de solicitudes de las aplicaciones cliente a, por ejemplo, 10 solicitudes por segundo, puede que sea necesario desarrollar gran cantidad de lógica. Gracias a Azure API Management, no es necesario escribir ninguna lógica personalizada si integras Azure Functions con API Management.

En esta receta, aprenderemos cómo restringir a los clientes el acceso de API solo una vez por minuto para una dirección IP determinada. A continuación, se proporcionan los pasos de alto nivel que seguiremos:

  1. Crear un servicio Azure API Management
  2. Integrar Azure Functions con API Management
  3. Configurar la limitación de solicitudes mediante políticas de entrada
  4. Probar la configuración de política de entrada de límite de velocidad

Preparación

Para empezar, necesitamos crear un servicio Azure API Management mediante los pasos siguientes:

  1. Busca API Management y proporciona todos los detalles siguientes. En el ejemplo siguiente, he elegido el nivel de precios para Desarrollador. No obstante, para tus aplicaciones de producción, deberás seleccionar niveles de precios que no sean para desarrolladores (Básico/Estándar/Premium), ya que el nivel de Desarrollador (sin SLA) no proporciona ningún SLA. Una vez que hayas revisado todos los detalles, haz clic en el botón Crear:
  • En el momento de redactar la receta, tardó aproximadamente 30 minutos en crearse una instancia de API Management. Una vez creada, podrás verla en la hoja de servicios API Management:

Cómo hacerlo…

Con el fin de aprovechar las capacidades API Management, necesitamos integrar los puntos de conexión de servicio (en nuestro caso, los desencadenadores de HTTP que hemos creado) con el servicio API Management. En esta sección indicaremos los pasos necesarios para la integración. Vamos a comenzar integrando los dos.

Integrar Azure Functions con API Management

Sigue estos pasos:

  1. Ve a la hoja de API de la Instancia de API Management que has creado  y haz clic en el icono de la Function App.
  2. Aparecerá la ventana emergente Crear a partir de Function App, donde puedes hacer clic en el botón Examinar y se abrirá una barra lateral con el título Importar Azure Functions, donde se pueden configurar las aplicaciones de función. Haz clic en el botón Configurar el parámetro obligatorio para ver todas las aplicaciones de función que contengan desencadenadores de HTTP. Una vez que hayas seleccionado la Function App, haz clic en el  botón Seleccionar.
  3. El siguiente paso es elegir el desencadenador de HTTP que deseas integrar con Azure API Management. Después de hacer clic en el botón Seleccionar, como se ha indicado en el paso anterior, aparecerán todos los desencadenadores de HTTP asociados con la aplicación de función seleccionada, como se muestra en la siguiente captura de pantalla. He elegido un solo desencadenador de HTTP para que resulte más sencillo:
  • Una vez realizados todos los pasos anteriores, aparecerá la ventana emergente Crear a partir de Function App, con un aspecto similar al siguiente. Cuando hayas revisado todos los datos, haz clic en el botón Crear:
  • Si todo va bien, deberías ver una pantalla como la de la captura  siguiente. Ya hemos terminado con la integración de Azure Functions  con API Management:

Configurar la limitación de solicitudes mediante políticas de entrada

Sigue estos pasos:

  1. Como se muestra en la captura de pantalla anterior, selecciona la operación requerida (GET) y haz clic en el enlace del editor de políticas de entrada (labeled 3), que abrirá el editor de políticas.

API Management nos permite controlar el comportamiento de las API de back-end (en nuestro caso, los desencadenadores de HTTP) mediante las políticas de API Management. Puedes controlar las respuestas de solicitud de entrada y de salida. Puedes obtener más información sobre este tema en https://docs.microsoft.com/azure/ api-management/api-management-howto-policies

  • Como tenemos que restringir la tasa de solicitudes dentro de API Management antes de enviar la solicitud a la Function App de back-end, es necesario configurar el límite de velocidad en la política de entrada. Crea una política nueva, tal como se muestra, con un valor de 1 para el atributo de llamadas y un valor de 60 (en segundos) para el atributo del período de renovación. Por último, define el valor de counter-key en la dirección IP de la aplicación cliente:

Con esta política de entrada, estaremos indicando a API Management que restrinja una solicitud por minuto para una dirección IP determinada.

  • Antes de probar la limitación, nos queda un último paso que consiste en publicar la API. Para ello, ve a la pestaña Configuración del paso anterior y asocia la API a un producto publicado (en mi caso, tengo un producto de inicio predeterminado que ya está publicado). Como se muestra en la captura de pantalla siguiente, selecciona el producto necesario y haz clic en el  botón Guardar:

Probar la configuración de política de entrada de límite de velocidad

Sigue estos pasos:

  1. Ve a la pestaña Prueba y agrega los parámetros o encabezados requeridos previstos por el desencadenador de HTTP. En mi caso, mi desencadenador de HTTP requiere un parámetro denominado «name».
  2. Ahora, haz clic en el botón Enviar que aparece tras completar el paso anterior para realizar tu primera solicitud. Debería aparecer algo como lo siguiente después de obtener una respuesta del back-end:
  • A continuación, haz clic inmediatamente en el botón Enviar. Como se muestra aquí, debería mostrarse un error, ya que nuestra regla de política  de entrada tan solo permite una solicitud por minuto para una dirección  IP específica:

Cómo funciona…

En esta receta, hemos creado una instancia de Azure API Management y hemos integrado una Azure Function App para aprovechar las funciones de API Management. Una vez integradas, hemos creado una política de entrada que restringe a los clientes a realizar una sola llamada por minuto desde una dirección IP determinada. A continuación, se muestra un diagrama de alto nivel que representa todo el proceso:

Acceder de forma segura a SQL Database desde Azure Functions mediante Managed Service Identity

En una de nuestras recetas, Interacciones de Azure SQL Database mediante Azure

Functions del capítulo 3, Integración perfecta de Azure Functions con los Servicios de Azure, hemos aprendido a obtener acceso a una instancia de SQL Database y a sus objetos desde Azure Functions proporcionando la cadena de conexión (nombre de usuario y contraseña).

Supongamos que, por cualquier motivo, cambias la contraseña de una cuenta, de tal manera que las aplicaciones que utilizan la cuenta ya no pueden obtener acceso a esta. Como desarrollador, ¿no resultaría útil que existiera un recurso en el que no tuvieras que preocuparte por las credenciales y, en su lugar, la plataforma se encargase de la autenticación? En esta receta, aprenderemos a obtener acceso a una  instancia de SQL Database desde una función de Azure sin proporcionar un identificador de usuario ni una contraseña a través de una función denominada Managed Service Identity.

En el momento de redactar esta receta, el código relacionado con la recuperación del token de acceso solo estaba disponible con Azure Functions v1 (.NET Framework), pero no con v2 (.NET Core). Para cuando estés leyendo este libro, es posible que ya esté disponible la última versión de .NET Core Framework, por lo que esta receta debería funcionar también con el runtime de Azure Functions v2.

Preparación

Esta receta nos indica cómo crear Azure Functions (con el runtime v1) y la base de datos SQL en el mismo grupo de recursos. Si no las has creado, créalas primero  y vuelve luego a esta receta para continuar. Estos son los pasos que vamos a seguir en esta receta:

  1. Crear una aplicación de función con Visual Studio 2017 con el runtime v1
  2. Crear un SQL Server lógico y una SQL Database
  3. Habilitar Managed Service Identity desde el portal
  4. Recuperar información de Managed Service Identity mediante la CLI de Azure
  5. Permitir el acceso de SQL Server a la nueva Managed Service Identity
  6. Ejecutar el desencadenador de HTTP y probarlo

Cómo hacerlo…

En esta receta, vamos a seguir estos pasos:

  1. Crear una aplicación de función con Visual Studio 2017 con el runtime v1
  2. Crear un SQL Server lógico y una SQL Database
  3. Habilitar la Managed Service Identity

Crear una aplicación de función con Visual Studio 2017 con el runtime v1

Sigue estos pasos:

  1. Crea una aplicación de función nueva con el runtime de Azure Functions v1.
  2. Una vez creado el desencadenador de HTTP, reemplaza la función por el código siguiente:

public static class HttpTriggerWithMSI

    {

        [FunctionName(«HttpTriggerWithMSI»)]

        public static async Task<HttpResponseMessage> Run([HttpTr igger(AuthorizationLevel.Anonymous, «get», «post», Route = null)]

HttpRequestMessage req, TraceWriter log)

        {

            log.Info(«C# HTTP trigger function processed a

request.»);              string firstname = string.Empty, lastname = string.

Empty, email = string.Empty, devicelist = string.Empty;

             dynamic data = await req.Content. ReadAsAsync<object>();

            firstname = data?.firstname;             lastname = data?.lastname;             email = data?.email;             devicelist = data?.devicelist;

            SqlConnection con = null;

            try             {

                string query = «INSERT INTO EmployeeInfo

(firstname,lastname, email, devicelist) » + «VALUES (@firstname,@

lastname, @email, @devicelist) «;

                con = new

                 SqlConnection(«Server=tcp:dbserver.database.

windows.net,1433;Initial Catalog=database;Persist Security Info=Fa lse;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertifi

cate=False;Connection Timeout=30;»);

                SqlCommand cmd = new SqlCommand(query, con);

                con.AccessToken = (new

AzureServiceTokenProvider()).GetAccessTokenAsync(«https://

database.windows.net/»).Result;

                 cmd.Parameters.Add(«@firstname», SqlDbType.

VarChar,

                 50).Value = firstname;

                cmd.Parameters.Add(«@lastname», SqlDbType.VarChar,

50)

                 .Value = lastname;

                cmd.Parameters.Add(«@email», SqlDbType.VarChar,

50)

                 .Value = email;                 cmd.Parameters.Add(«@devicelist», SqlDbType.

VarChar)

                 .Value = devicelist;                 con.Open();                 cmd.ExecuteNonQuery();

            }

            catch (Exception ex)

            {

                throw ex;

            }             finally

            {

                if (con != null)

                {

                    con.Close();

                }

            }

            return req.CreateResponse(HttpStatusCode.OK, «Hello,

Successfully inserted the data»);

        }

El código anterior es el código que copié del capítulo 3, Integración perfecta de Azure Functions con los Servicios de Azure, con los cambios siguientes, pero la cadena de conexión no contiene el Id. de usuario ni la contraseña.

  1. Agrega una nueva línea de código para recuperar el token de acceso:

con.AccessToken = (new AzureServiceTokenProvider()). GetAccessTokenAsync(«https://database.windows.net/»).Result;

  • Agrega los siguientes paquetes NuGet a la Function App:

Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory

Install-Package Microsoft.Azure.Services.AppAuthentication

  • Asegúrate de que no hay errores de compilación y, a continuación, publica la Function App en Azure. Este paso garantiza que la aplicación de función se cree con el runtime v1. Haz clic en el botón Publicar, que abre la ventana emergente siguiente:
  • A continuación, proporciona el Grupo de recursos y demás datos, como se muestra en la siguiente captura de pantalla, y haz clic en el botón Crear:

Crear un SQL Server lógico y una SQL Database

Crea un SQL Server y una base de datos de SQL en el mismo grupo de recursos en el que hayas creado la Azure Function App. En mi caso, mi nombre de grupo de recursos es AzureServerlessCookbookv1.

Habilitar la Managed Service Identity

Sigue estos pasos:

  1. Ve a las características de la Plataforma de la Function App y haz clic en Managed Service Identity.
  2. En la pestaña Managed Service Identity, haz clic en Activada y en Guardar, como se muestra a continuación:

Recuperar información de Managed Service Identity

Sigue estos pasos:

  1. Autentica la identidad de tu cuenta de Azure mediante la CLI de Azure. Para ello, ejecuta el comando az login en el símbolo del sistema, como se muestra en la siguiente captura de pantalla:
  • Se te pedirá que proporciones las credenciales de tu cuenta de Azure para iniciar sesión en Azure Portal. Una vez que hayas proporcionado tus credenciales, mostrará las suscripciones disponibles en la consola  de comandos.
  • Ahora vamos a recuperar los datos de la entidad de servicio ejecutando el siguiente comando:

az resource show –name <<Function App Name>> –resource-group <<Resource Group>> –resource-type Microsoft.Web/sites –query identity

  • Si has configurado la identidad administrada correctamente, aparecerá algo similar a lo siguiente como salida del comando anterior:
  • Anota el valor de PrincipalID, que se recupera en el paso anterior. Lo vamos a utilizar en la sección siguiente.

Permitir el acceso de SQL Server a la nueva Managed Service Identity

En esta sección, vamos a crear un usuario administrador que tenga acceso al SQL Server que hemos creado anteriormente:

  1. Ejecuta el siguiente comando en el símbolo del sistema pasando el valor de PrincipalID que anotaste en la sección anterior:

az sql server ad-admin create –resource-group

AzureServerlessCookbookv1 –server-name azuresqlmsidbserver

–display-name sqladminuser –object-id <Principe Id>

  • Al ejecutar el comando anterior, se crea un nuevo usuario administrador en la base de datos maestra de SQL Server.
  • Crea una tabla denominada EmployeeInfo utilizando el siguiente script:

CREATE TABLE [dbo].[EmployeeInfo](  [PKEmployeeId] [bigint]

IDENTITY(1,1) NOT NULL,  [firstname] [varchar](50) NOT NULL, 

[lastname] [varchar](50) NULL,  [email] [varchar](50) NOT NULL, 

[devicelist] [varchar](max) NULL,  CONSTRAINT [PK_EmployeeInfo]

PRIMARY KEY CLUSTERED  (  [PKEmployeeId] ASC  )  )

Ejecutar el desencadenador de HTTP y probarlo

Sigue estos pasos:

  1. Abre Postman y envía una solicitud, tal como se muestra:
  • Ahora revisemos la SQL Database para comprobar si se ha insertado  el registro:

Y eso no es todo…

Asegúrate de que la clase tiene todos los espacios de nombres siguientes:

using System.Net; using System.Net.Http; using System.Threading.Tasks; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Azure.WebJobs.Host; using System.Data.SqlClient; using System.Data; using System; using Microsoft.Azure.Services.AppAuthentication;

Consulta también

Consulta la receta Interacciones de Azure SQL Database mediante Azure Functions del capítulo 3, Integración perfecta de Azure Functions con los Servicios de Azure.

Código compartido en Azure Functions mediante bibliotecas de clases

Has aprendido a reutilizar un método auxiliar en una aplicación de función de Azure. Sin embargo, no se puede reutilizar en otras aplicaciones de función ni en ningún otro tipo de aplicación, como una aplicación web o una aplicación WPF. En esta receta, vamos a desarrollar y crear un archivo .dll nuevo y aprenderás a usar las clases y sus métodos en Azure Functions.

Cómo hacerlo…

Sigue estos pasos:

  1. Crea una aplicación de Biblioteca de clases nueva mediante Visual Studio. Yo he utilizado Visual Studio 2017:
  • Crea una clase nueva denominada Helper y pega el código siguiente en el archivo de clase nuevo:

namespace Utilities

{

    public class Helper

    {

        public static string GetReusableFunctionOutput()

        {

            return «This is an output from a Resuable Library

across functions»;

        }

    }

}

  • Cambia la configuración de compilación a Lanzamiento y compila la aplicación para crear el archivo .dll que se utilizará en Azure Functions.
  • Abre el Editor de App Service de la Function App a través del  botón Editor de App Service, que está disponible en Características  de la plataforma.
  • A continuación, crea una nueva carpeta bin. Para ello, haz clic con el botón derecho en el área vacía debajo de los archivos ubicados en WWWROOT.
  • Después de hacer clic en el elemento Nueva carpeta de la pantalla resultante, aparecerá un cuadro de texto nuevo en el que debes especificar el  nombre «bin».
  • A continuación, haz clic con el botón derecho en la carpeta bin y selecciona la opción Cargar archivos para cargar el archivo .dll que hemos creado en Visual Studio.
  • Esto es lo que se muestra después de cargar el archivo .dll en la carpeta bin:
  • Ve a la Azure Function donde deseas utilizar el método compartido. Con fines de demostración, he creado dos Azure Functions (un desencadenador de HTTP y un desencadenador de temporizador):
  1. A continuación, iremos a la función ReusableMethodCaller1 y realizaremos los siguientes cambios:

°     Agrega una nueva política #r, como se indica a continuación, al método run.csx de la Azure Function ReusableMethodCaller1.

Observa que, en este caso, se requiere .dll:

#r «../bin/Utilities.dll»

° Agrega un espacio de nombres nuevo, como se muestra  a continuación: using Utilities;

  1. Ahora ya estamos listos para utilizar el método compartido

GetReusableFunctionOutput en nuestra Azure Function. A continuación, reemplaza el desencadenador de HTTP con lo siguiente: log.LogInformation(Helper.GetReusableFunctionOutput());

  1. Al ejecutar la aplicación, deberías ver el siguiente mensaje en los registros:
  1. Repite los mismos pasos para agregar la referencia y el espacio de nombres de la biblioteca de utilidades, también en la segunda Azure Function,  ReusableMethodCaller2. Si has realizado los cambios correctamente, debería mostrarse algo muy parecido a lo siguiente:

Hemos creado un archivo .dll que contiene el código reutilizable que se puede utilizar en cualquiera de las Azure Functions que requieren la funcionalidad disponible a través del archivo .dll.

Con el archivo .dll ya listo, hemos creado una carpeta bin en la Function App  y hemos agregado el archivo .dll a la carpeta bin.

Ten en cuenta que hemos agregado la carpeta bin al directorio WWWROOT para que esté disponible para todas las Azure Functions disponibles en la aplicación de función.

Y eso no es todo…

Si deseas utilizar el código compartido únicamente en una función, debes  agregar la carpeta bin junto con el archivo .dll en la carpeta de la Azure  Function correspondiente.

Otra ventaja importante del uso de bibliotecas de clases es que mejora el rendimiento, dado que ya están compiladas y listas para su ejecución.

Usar clases fuertemente tipadas en  Azure Functions

En los capítulos iniciales, hemos desarrollado un desencadenador de HTTP denominado RegisterUser que actúa como una API web y puede consumirlo cualquier aplicación capaz de realizar solicitudes HTTP. Sin embargo, puede haber otros requisitos en situaciones en las que existan varias aplicaciones que creen mensajes en una cola con los datos necesarios para crear un usuario. Para simplificar la tarea, vamos a utilizar el explorador de Azure Storage para crear un mensaje  de la cola.

En esta receta, vamos a aprender a obtener los datos del usuario de la cola mediante objetos fuertemente tipados.

Preparación

Antes de seguir avanzando, vamos a seguir estos pasos:

  1. Crea una cuenta de Azure Storage (yo he creado azurefunctionscookbook) en tu suscripción de Azure.
  2. Instala el explorador de Microsoft Azure Storage si aún no las instalado.
  3. Una vez creado el explorador de Azure Storage, conéctate a la cuenta de Azure Storage.

Cómo hacerlo…

Sigue estos pasos:

  1. Utiliza el explorador de Azure Storage para crear una cola denominada registeruserqueue en la cuenta de Azure Storage denominada azurefunctionscookbook. Se presupone que todas las demás aplicaciones estarían creando mensajes en la cola registeruserqueue.
  2. Ve a Azure Functions y crea una Azure Function nueva mediante el desencadenador de Azure Queue Storage y, a continuación, selecciona la cola que hemos creado.
  3. Es posible que se te pida que instales las extensiones de Azure Storage si no están ya instaladas. Una vez instaladas las extensiones, proporciona los datos de la cola y haz clic en el botón Crear, como se muestra en la siguiente captura de pantalla:
  • Una vez creada la función, reemplaza el código predeterminado con el siguiente código. Siempre que se crea un mensaje de cola, el mensaje JSON se deserializa automáticamente y se rellena en un objeto denominado myQueueItem. En el siguiente código, solo vamos a imprimir los valores de los objetos de la ventana Registros:

using System;

public static void Run(User myQueueItem, ILogger log) {

    log.LogInformation($»A Message has been created for a new User»);

    log.LogInformation($»First name: {myQueueItem.firstname}» );     log.LogInformation($»Last name: {myQueueItem.lastname}» );     log.LogInformation($»email: {myQueueItem.email}» );     log.LogInformation($»Profile Url: {myQueueItem.ProfilePicUrl}»

);

}

public class User

{

    public string firstname { get;set;}     public string lastname { get;set;}     public string email { get;set;}     public string ProfilePicUrl { get;set;}

}

  • Ve al explorador de Azure Storage y crea un nuevo mensaje en registeruserqueue, como se muestra en la siguiente captura de pantalla:
  • Haz clic en Aceptar para crear el mensaje de cola, vuelve a la Azure Function y revisa los registros, como se muestra en la siguiente captura de pantalla:

Cómo funciona…

Hemos desarrollado una nueva función de cola que se activa cuando se agrega un nuevo mensaje a la cola. Hemos creado un nuevo mensaje de la cola con todos los datos necesarios para crear el usuario. Puedes seguir reutilizando el código de la Azure Function para pasar el objeto de usuario (en este caso, myQueueItem) a la clase de capa de base de datos, que se encarga de insertar los datos en una base de datos  o en cualquier otro medio persistente.

Y eso no es todo…

En esta receta, el tipo del parámetro de mensaje de cola aceptado por el método Run ha sido User. El runtime de Azure Functions se encargará de deserializar el mensaje JSON disponible en la cola para el tipo personalizado; en nuestro caso, es «user».