Dapr en Azure Functions (1/N)


Y continuamos hablando sobre Dapr. En este caso, sobre la extensión para Azure Functions que permite que una función interactúe con Dapr para crear aplicaciones nativas en Cloud. Con esta extensión, es posible unir ambos mundos: Serverless y Event-Driven que pueden usar las capacidades de Dapr.

En particular, construiremos dos funciones «QueueReader» y «EmailSender» para probar las distintas posiblidades que nos brinda Dapr: Read from a queue, State Store, Pub/Sub, Binding, Secrets and Service Invocation, hosteadas sobre AKS.

Nota: Actualmente, esta extensión está disponible para Kubernetes o IoT Edge sin embargo, no lo está para ser hosteada Azure Functions.

Como simpre, el código completo puedes encontrarlo aquí, en mi github y recuerda que en la Introducción a Dapr .NET SDK, ya vimos muchos de los puntos que trataremos en este post.

Este artículo se compone de dos posts. El primero es el que nos ocupa y el segundo aborda el despliegue de la solución a Kuberneetes/AKS:

Comenzaremos en este primero, ejecutando las siguientes instrucciones desde línea de comandos. ¡Tendremos que tener instalado dotnet y Azure Functions Core Tools!

mkdir hello-functions
cd hello-functions
func init hello-functions // select dotnet as worker runtime
dotnet add package Microsoft.Azure.WebJobs.Extensions.Storage
dotnet add package Dapr.AzureFunctions.Extension
func new QueueReader # QueueTrigger
func new EmailSender # ServiceBusTopicTrigger

A continuación, actualizamos el código de las funciones QueReader y EmailSender:

public static class QueueReader
{
    [FunctionName("QueueReader")]
    public static async Task Run(
        [DaprBindingTrigger(BindingName = "queuebinding")] Data data,
        [DaprState("statestore", Key = "{data.Id}")] IAsyncCollector<string> state,
        [DaprPublish(PubSubName = "pubsub", Topic = "greatings")] IAsyncCollector<string> pubsub,
        ILogger log)
    {
        log.LogInformation($"C# Queue trigger function initiated");

        await state.AddAsync(data.Name);
        await pubsub.AddAsync(data.Name);

        log.LogInformation($"C# Queue trigger function processed: {data.Name}");            
    }
}
public static class EmailSender
{
    [FunctionName("EmailSender")]
    public static async Task<IActionResult> Run(
        [DaprTopicTrigger("pubsub", Topic = "greatings")] CloudEvent @event,
        [DaprSecret("secretstore", "sampleKey")] IDictionary<string, string> secret,
        [DaprBinding(BindingName = "mail", Operation = "create")] IAsyncCollector<DaprBindingMessage> mailer,
        ILogger log)
    {
        log.LogInformation($"C# ServiceBus topic trigger function initiated");

        var msg = $"Just a sample: User '{@event.Data}' are using '{secret["sampleKey"]}' key.";
        var content = new InvokeMethodParameters()
        {
            Body = msg
        };
        await invoke.AddAsync(content);

        await mailer.AddAsync(new DaprBindingMessage(msg);

        log.LogInformation($"Email Sender end !");

        return new OkResult();
    }
}

En cuanto a los componentes dapr, básicamente se trata de los mismos que ya vimos en la introducción a Dapr, a excepción del envío de email con Twilio – SendGrid, que pasa a ser el siguiente:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: mail  
spec:
  type: bindings.twilio.sendgrid  
  metadata:
  - name: emailFrom
    value: "<TU-EMAIL-FROM>"
  - name: emailTo
    value: "<TU-EMAIL-TO>"
  - name: subject
    value: "Dapr using azure functions" 
  - name: apiKey
    secretKeyRef:
      name: sendgridKey      
auth:
  secretStore: secretstore

Twilio SendGrid

Para configurar el envío de emails usando SendGrid seguimos estos pasos:

  • Desde el Portal de Azure creamos un nuevo recurso Twilio – SendGrid y completamos el progreso al igual que para crear cualquier otro recurso de Azure. ¡Eso si, e trata de un proveedor externo por lo que al final saldrás del Portal de Azure para su configuración!
  • Seleccionamos el plan gratuito
  • Completado el proceso, accedemos a esta url : https://app.sendgrid.com/ y,
  • Creamos y configuramos un Sender Identity y,
  • Un nuevo APIKey tal y como se muestra en la siguiente imagen.
  • En nuestro Key Vault intoducimos un nuevo secret «sendGrindKey» con el valor del APIKey obtenido en el paso anterior.
  • Adicionalmetne, introducimos un nuevo secret «sampleyKey» con un valor cualquiera. ¡Se trata simplemente de conocer el acceso y uso de este secret de manera explicita desde nuestra azure function.!

En lo que respecta a la configuración del componente de Key Vault (secrets.yaml), necesitamos el spnClientId, para lo que tenemos que ejecutar desde linea de comandos la siguiente instrucción.

az ad sp list --display-name ServicePrincipal

Asi como esta otra para descargar el certificado (.pfx). El path donde lo descarguemos debe coincidir con el valor/ruta que demos a la propiedad spnCertificateFile, en el fichero «secrets.yaml«.

az keyvault secret download --vault-name <KEY-VAULT-NAME> --name CertName --encoding base64 --file c:\users\<USER-NAME>\<FILE-NAME>.pfx

Una vez completado estos puntos, ya tenemos listo todos los componentes Dapr. ¡ De los que no hemos hablado, recueda que tienes todo su detalle en github y ya lo comentamos en posts antriores!:

Ejecutando la aplicación

Ahora que ya tenemos todo configurado y tenemos todas las piezas, veamos como es el flujo y como funciona nuestra aplicación según la arquitectura planteada:

  1. En primer lugar, DaprBindingTrigger, permanece escuchando en la cola para leer cualquier mensaje que depositemos en la misma.
  2. DaprState permite almacenar el mensaje obtenido de la cola en el Table Storage de Azure.
  3. DaprPublish, publica un mensaje en el Azure Service Bus, para poder comunicarse así, con la siguiente función EmailSender.
  4. DaprTopicTrigger. Recoge el mensaje enviado por la función QueueReader, en concreto en «name».
  5. DaprSecret. Obtiene del Key Vault la clave sampleKey para usarla en el mensaje a envíar.
  6. DaprBinding. Utiliza el componente Dapr mail (mail.yaml), que a su vez hace uso del secreto sendgridKey (de Key Vault), para obtener el ApiKey de SendGrid y hacer el envío del email, a la dirección de email configurada también en dicho componente.

Finalmente, para ponerlo to en marcha:

  • Introducimos el siguiente mensaje en la cola de Azure Storage, vía «Microsoft Azure Storage Explorer» (versión web) o bien desde la sección «Data Storage – Queues», ambas opciones en el Portal de Azure.
{
"id": 1,
"name" : "Juanlu"
}
  • Y nos aseguramos de desmarcar la casilla «Encode the message body in Base64«.
  • Ejecutamos el siguiente comando para poner en ejecución ambas funciones y comienza «el juego».
dapr run --app-id hello-functions --dapr-http-port 3501 -p 3001 --components-path .\dapr\components -- func host start

Todas la piezas se ponen en marcha y finalmente el email es enviado.

Las dos Azure Functions en ejecución y flujo completado con el mensaje/name «Juanlu»
El name «Juanlu» es almacenado en Azure Table Storage
Email recibido con el título y mensaje esperado (via Twilio SendGrid).

No dejes de probar esta arquitectura, creo que es un buen ejemplo para probar la mayoria de los binding/trigger de Dapr en Azure Functions y entender todo su funcionamiento.

Happy #Dapr coding !!

Referencias

2 comentarios sobre “Dapr en Azure Functions (1/N)

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.