Liaison de sortie Azure Event Grid pour Azure Functions

Utilisez la liaison de sortie Event Grid pour écrire des événements dans une rubrique personnalisée. Vous devez avoir une clé d’accès valide pour la rubrique personnalisée. La liaison de sortie Event Grid ne prend pas en charge les jetons de signature d’accès partagé (SAP).

Pour plus d’informations sur l’installation et les détails de configuration, consultez Utilisation des déclencheurs et des liaisons Event Grid dans Azure Functions.

Important

Cet article utilise des onglets pour prendre en charge plusieurs versions du modèle de programmation Node.js. Le modèle v4 est en disponibilité générale. Il est conçu pour offrir une expérience plus flexible et intuitive aux développeurs JavaScript et TypeScript. Pour plus d’informations sur le fonctionnement du modèle v4, reportez-vous au guide du développeur Azure Functions Node.js. Pour plus d’informations sur les différences entre v3 et v4, consultez le guide de migration.

Azure Functions prend en charge deux modèles de programmation pour Python. La façon dont vous définissez vos liaisons dépend du modèle de programmation choisi.

Le modèle de programmation Python v2 vous permet de définir des liaisons à l'aide d’éléments décoratifs directement dans le code de votre fonction Python. Pour plus d’informations, consultez le guide des développeurs Python.

Cet article prend en compte les deux modèles de programmation.

Important

La liaison de sortie Event Grid est disponible seulement pour Functions 2.x et ultérieur.

Exemple

Le type du paramètre de sortie utilisé avec une liaison de sortie Event Grid dépend de la version du runtime Functions, de la version de l’extension de liaison et de la modalité de la fonction C#. La fonction C# peut être créée à l’aide de l’un des modes C# suivants :

L’exemple suivant montre l’utilisation du type personnalisé à la fois dans le déclencheur et dans une liaison de sortie Event Grid :

using System;
using System.Collections.Generic;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

namespace SampleApp
{
    public static class EventGridFunction
    {
        [Function(nameof(EventGridFunction))]
        [EventGridOutput(TopicEndpointUri = "MyEventGridTopicUriSetting", TopicKeySetting = "MyEventGridTopicKeySetting")]
        public static MyEventType Run([EventGridTrigger] MyEventType input, FunctionContext context)
        {
            var logger = context.GetLogger(nameof(EventGridFunction));

            logger.LogInformation(input.Data.ToString());

            var outputEvent = new MyEventType()
            {
                Id = "unique-id",
                Subject = "abc-subject",
                Data = new Dictionary<string, object>
                {
                    { "myKey", "myValue" }
                }
            };

            return outputEvent;
        }
    }

    public class MyEventType
    {
        public string Id { get; set; }

        public string Topic { get; set; }

        public string Subject { get; set; }

        public string EventType { get; set; }

        public DateTime EventTime { get; set; }

        public IDictionary<string, object> Data { get; set; }
    }
}

L’exemple suivant illustre une fonction Java qui écrit un message à une rubrique personnalisée Event Grid. La fonction utilise la méthode setValue de la liaison pour générer une chaîne.

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<String> outputEvent,
            final ExecutionContext context) {
        context.getLogger().info("Java EventGrid trigger processed a request." + content);
        final String eventGridOutputDocument = "{\"id\": \"1807\", \"eventType\": \"recordInserted\", \"subject\": \"myapp/cars/java\", \"eventTime\":\"2017-08-10T21:03:07+00:00\", \"data\": {\"make\": \"Ducati\",\"model\": \"Monster\"}, \"dataVersion\": \"1.0\"}";
        outputEvent.setValue(eventGridOutputDocument);
    }
}

Vous pouvez également utiliser une classe POJO pour envoyer des messages Event Grid.

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<EventGridEvent> outputEvent,
            final ExecutionContext context) {
        context.getLogger().info("Java EventGrid trigger processed a request." + content);

        final EventGridEvent eventGridOutputDocument = new EventGridEvent();
        eventGridOutputDocument.setId("1807");
        eventGridOutputDocument.setEventType("recordInserted");
        eventGridOutputDocument.setEventTime("2017-08-10T21:03:07+00:00");
        eventGridOutputDocument.setDataVersion("1.0");
        eventGridOutputDocument.setSubject("myapp/cars/java");
        eventGridOutputDocument.setData("{\"make\": \"Ducati\",\"model\":\"monster\"");

        outputEvent.setValue(eventGridOutputDocument);
    }
}

class EventGridEvent {
    private String id;
    private String eventType;
    private String subject;
    private String eventTime;
    private String dataVersion;
    private String data;

    public String getId() {
        return id;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getDataVersion() {
        return dataVersion;
    }

    public void setDataVersion(String dataVersion) {
        this.dataVersion = dataVersion;
    }

    public String getEventTime() {
        return eventTime;
    }

    public void setEventTime(String eventTime) {
        this.eventTime = eventTime;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getEventType() {
        return eventType;
    }

    public void setEventType(String eventType) {
        this.eventType = eventType;
    }

    public void setId(String id) {
        this.id = id;
    }  
}

L’exemple suivant montre une fonction TypeScript déclenchée par un minuteur qui génère un seul événement :

import { app, EventGridPartialEvent, InvocationContext, output, Timer } from '@azure/functions';

export async function timerTrigger1(myTimer: Timer, context: InvocationContext): Promise<EventGridPartialEvent> {
    const timeStamp = new Date().toISOString();
    return {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    };
}

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: output.eventGrid({
        topicEndpointUri: 'MyEventGridTopicUriSetting',
        topicKeySetting: 'MyEventGridTopicKeySetting',
    }),
    handler: timerTrigger1,
});

Pour générer plusieurs événements, retournez un tableau au lieu d’un seul objet. Par exemple :

const timeStamp = new Date().toISOString();
return [
    {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    },
    {
        id: 'message-id-2',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Doe',
        },
        eventTime: timeStamp,
    },
];

L’exemple suivant montre une fonction JavaScript déclenchée par un minuteur qui génère un seul événement :

const { app, output } = require('@azure/functions');

const eventGridOutput = output.eventGrid({
    topicEndpointUri: 'MyEventGridTopicUriSetting',
    topicKeySetting: 'MyEventGridTopicKeySetting',
});

app.timer('timerTrigger1', {
    schedule: '0 */5 * * * *',
    return: eventGridOutput,
    handler: (myTimer, context) => {
        const timeStamp = new Date().toISOString();
        return {
            id: 'message-id',
            subject: 'subject-name',
            dataVersion: '1.0',
            eventType: 'event-type',
            data: {
                name: 'John Henry',
            },
            eventTime: timeStamp,
        };
    },
});

Pour générer plusieurs événements, retournez un tableau au lieu d’un seul objet. Par exemple :

const timeStamp = new Date().toISOString();
return [
    {
        id: 'message-id',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Henry',
        },
        eventTime: timeStamp,
    },
    {
        id: 'message-id-2',
        subject: 'subject-name',
        dataVersion: '1.0',
        eventType: 'event-type',
        data: {
            name: 'John Doe',
        },
        eventTime: timeStamp,
    },
];

L’exemple suivant montre comment configurer une fonction pour générer un message d’événement Event Grid. La section dans laquelle type a la valeur eventGrid configure les valeurs nécessaires pour établir une liaison de sortie Event Grid.

{
  "bindings": [
    {
      "type": "eventGrid",
      "name": "outputEvent",
      "topicEndpointUri": "MyEventGridTopicUriSetting",
      "topicKeySetting": "MyEventGridTopicKeySetting",
      "direction": "out"
    },
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}

Dans votre fonction, utilisez Push-OutputBinding pour envoyer un événement à une rubrique personnalisée par le biais de la liaison de sortie Event Grid.

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$message = $Request.Query.Message

Push-OutputBinding -Name outputEvent -Value  @{
    id = "1"
    eventType = "testEvent"
    subject = "testapp/testPublish"
    eventTime = "2020-08-27T21:03:07+00:00"
    data = @{
        Message = $message
    }
    dataVersion = "1.0"
}

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = 200
    Body = "OK"
})

L'exemple suivant illustre une liaison entre un déclencheur et une fonction Python qui utilise la liaison. Il envoie ensuite un événement à la rubrique personnalisée, comme spécifié par topicEndpointUri. L’exemple varie selon l’utilisation du modèle de programmation Python v1 ou v2.

Voici la fonction dans le fichier function_app.py :

import logging
import azure.functions as func
import datetime

app = func.FunctionApp()

@app.function_name(name="eventgrid_output")
@app.event_grid_trigger(arg_name="eventGridEvent")
@app.event_grid_output(
    arg_name="outputEvent",
    topic_endpoint_uri="MyEventGridTopicUriSetting",
    topic_key_setting="MyEventGridTopicKeySetting")
def eventgrid_output(eventGridEvent: func.EventGridEvent, 
         outputEvent: func.Out[func.EventGridOutputEvent]) -> None:

    logging.log("eventGridEvent: ", eventGridEvent)

    outputEvent.set(
        func.EventGridOutputEvent(
            id="test-id",
            data={"tag1": "value1", "tag2": "value2"},
            subject="test-subject",
            event_type="test-event-1",
            event_time=datetime.datetime.utcnow(),
            data_version="1.0"))

Attributs

Les bibliothèques C# In-process et de processus Worker isolé utilisent des attributs pour configurer la liaison. Le script C# utilise à la place un fichier de configuration function.json comme décrit dans le guide de script C#.

Le constructeur de l’attribut prend le nom d’un paramètre d’application qui contient le nom de la rubrique et le nom d’un paramètre d’application qui contient la clé de la rubrique.

Le tableau suivant présente les paramètres de EventGridOutputAttribute.

Paramètre Description
TopicEndpointUri Nom d’un paramètre d’application qui contient l’URI pour la rubrique personnalisée, comme MyTopicEndpointUri.
TopicKeySetting Nom d’un paramètre d’application qui contient une clé d’accès pour la rubrique personnalisée.
connexion* Valeur du préfixe commun pour le paramètre qui contient l'URI du point de terminaison du sujet. Pour en savoir plus sur le format de dénomination de ce paramètre d'application, reportez-vous à Authentification basée sur l'identité.

Annotations

Pour les classes Java, utilisez l’attribut EventGridAttribute.

Le constructeur de l’attribut prend le nom d’un paramètre d’application qui contient le nom de la rubrique et le nom d’un paramètre d’application qui contient la clé de la rubrique. Pour plus d’informations sur ces paramètres, consultez Sortie - configuration. Voici un exemple d’attribut EventGridOutput :

public class Function {
    @FunctionName("EventGridTriggerTest")
    public void run(@EventGridTrigger(name = "event") String content,
            @EventGridOutput(name = "outputEvent", topicEndpointUri = "MyEventGridTopicUriSetting", topicKeySetting = "MyEventGridTopicKeySetting") OutputBinding<String> outputEvent, final ExecutionContext context) {
            ...
    }
}

Configuration

Le tableau suivant explique les propriétés que vous pouvez définir pour l’objet options passé à la méthode output.eventGrid().

Propriété Description
topicEndpointUri Nom d’un paramètre d’application qui contient l’URI pour la rubrique personnalisée, comme MyTopicEndpointUri.
topicKeySetting Nom d’un paramètre d’application qui contient une clé d’accès pour la rubrique personnalisée.
connexion* Valeur du préfixe commun pour le paramètre qui contient l'URI du point de terminaison du sujet. Quand vous définissez la propriété connection, les propriétés topicEndpointUri et topicKeySetting ne doivent pas être définies. Pour en savoir plus sur le format de dénomination de ce paramètre d'application, reportez-vous à Authentification basée sur l'identité.

Configuration

Le tableau suivant décrit les propriétés de configuration de liaison que vous définissez dans le fichier function.json.

Propriété function.json Description
type Cette propriété doit être définie sur eventGrid.
direction Cette propriété doit être définie sur out. Ce paramètre est défini automatiquement lorsque vous créez la liaison dans le portail Azure.
name Nom de variable utilisé dans le code de la fonction qui représente l’événement.
topicEndpointUri Nom d’un paramètre d’application qui contient l’URI pour la rubrique personnalisée, comme MyTopicEndpointUri.
topicKeySetting Nom d’un paramètre d’application qui contient une clé d’accès pour la rubrique personnalisée.
connexion* Valeur du préfixe commun pour le paramètre qui contient l'URI du point de terminaison du sujet. Pour en savoir plus sur le format de dénomination de ce paramètre d'application, reportez-vous à Authentification basée sur l'identité.

*La prise en charge des connexions basées sur l'identité nécessite la version 3.3.x ou supérieure de l'extension.

Lorsque vous développez en local, ajoutez vos paramètres d’application dans le fichier local.settings.json de la collection Values.

Important

Assurez-vous de définir la valeur de TopicEndpointUri sur le nom d'un paramètre d'application contenant l'URI du sujet personnalisé. Ne spécifiez pas l’URI de la rubrique personnalisée directement dans cette propriété. Le même principe s'applique lors de l'utilisation de Connection.

Pour obtenir des exemples complets, consultez la section Exemple.

Utilisation

Le type de paramètre pris en charge par la liaison de sortie Event Grid dépend de la version du runtime Functions, de la version du package d’extension et de la modalité C# utilisée.

Quand vous souhaitez que la fonction écrive un seul événement, la liaison de sortie Event Grid peut se lier aux types suivants :

Type Description
string Événement sous forme de chaîne.
byte[] Octets du message de l’événement.
Types sérialisables JSON Objet représentant un événement JSON. Functions tente de sérialiser un objet POCO (Plain-Old CLR Object) en données JSON.

Quand vous souhaitez que la fonction écrive plusieurs événements, la liaison de sortie Event Grid peut se lier aux types suivants :

Type Description
T[]T est l’un des types d’événements uniques Tableau contenant plusieurs événements. Chaque entrée représente un événement.

Pour d’autres scénarios de sortie, créez et utilisez directement des types à partir d’Azure.Messaging.EventGrid.

Envoyez des messages individuels en appelant un paramètre de méthode, tel que out EventGridOutput paramName, et écrivez plusieurs messages avec ICollector<EventGridOutput>.

Accédez au message de sortie en retournant la valeur directement ou en utilisant context.extraOutputs.set().

Accédez à l’événement de sortie avec la cmdlet Push-OutputBinding pour envoyer un événement à la liaison de sortie Event Grid.

Il existe deux options pour produire en sortie un message Event Grid à partir d’une fonction :

  • Valeur de retour : Définissez la propriété name dans function.json sur $return. Avec cette configuration, la valeur renvoyée de la fonction est conservée sous la forme d’un message Event Grid.
  • Impératif : Passez une valeur à la méthode set du paramètre déclaré en tant que type Out. La valeur transmise à set est conservée en tant que message Event Grid.

Connexions

Vous pouvez vous authentifier de deux manières auprès d'un sujet Event Grid lorsque vous utilisez la liaison de sortie Event Grid :

Méthode d'authentification Description
utiliser une clé de sujet Définissez les propriétés TopicEndpointUri et TopicKeySetting, comme décrit dans Utiliser une clé de sujet.
Utiliser une identité Définissez la propriété Connection sur le nom d'un préfixe partagé pour plusieurs paramètres d'application, définissant ensemble l'authentification basée sur l'identité. Cette méthode est prise en charge lors de l'utilisation de la version 3.3.x ou supérieure de l'extension.

Utiliser une clé de sujet

Utilisez les étapes suivantes pour configurer une clé de sujet :

  1. suivez les étapes décrites dans Obtenir les clés d'accès pour obtenir la clé de rubrique pour votre sujet Event Grid.

  2. Dans les paramètres d'application, créez un paramètre qui définit la valeur clé du sujet. Utilisez le nom de ce paramètre pour la propriété TopicKeySetting de la liaison.

  3. Dans les paramètres de votre application, créez un paramètre qui définit le point de terminaison du sujet. Utilisez le nom de ce paramètre pour la propriété TopicEndpointUri de la liaison.

Authentification basée sur l’identité

Lorsque vous utilisez la version 3.3.x ou supérieure de l'extension, vous pouvez vous connecter à un sujet Event Grid en utilisant une identité Microsoft Entra pour éviter d'avoir à obtenir et à travailler avec des clés de sujet.

Vous devez créer un paramètre d’application qui renvoie l’URI du point de terminaison de rubrique. Le nom du paramètre doit combiner un préfixe commun unique (par exemple, myawesometopic) avec la valeur __topicEndpointUri. Ensuite, vous devez utiliser le préfixe commun (dans ce cas, myawesometopic) quand vous définissez la propriété Connection dans la liaison.

Dans ce mode, l’extension nécessite les propriétés suivantes :

Propriété Modèle de variable d’environnement Description Valeur d'exemple
URI de point de terminaison de la rubrique <CONNECTION_NAME_PREFIX>__topicEndpointUri Point de terminaison de la rubrique https://<topic-name>.centralus-1.eventgrid.azure.net/api/events

D'autres propriétés peuvent être utilisées pour personnaliser la connexion. Consultez Propriétés communes pour les connexions basées sur l’identité.

Remarque

Lorsque vous utilisez Azure App Configuration ou Key Vault pour fournir des paramètres pour les connexions basées sur l'identité managée, les noms de paramètres doivent utiliser un séparateur de clé valide tel que : ou / à la place de __ pour garantir que les noms sont bien résolus.

Par exemple : <CONNECTION_NAME_PREFIX>:topicEndpointUri.

Quand elles sont hébergées dans le service Azure Functions, les connexions basées sur une identité utilisent une identité managée. L’identité attribuée par le système est utilisée par défaut, bien qu’une identité attribuée par l’utilisateur puisse être spécifiée avec les propriétés credential et clientID. Notez que la configuration d’une identité affectée par l’utilisateur avec un ID de ressource n’est pas prise en charge. Lors d’une exécution dans d’autres contextes, tels que le développement local, votre identité de développeur est utilisée à la place, même si cela peut être personnalisé. Consultez Développement local avec connexions basées sur une identité.

Accorder l’autorisation à l’identité

Quelle que soit l’identité utilisée, elle doit avoir les autorisations nécessaires pour effectuer les actions prévues. Pour la plupart des services Azure, cela signifie que vous devez attribuer un rôle dans Azure RBAC en utilisant des rôles intégrés ou personnalisés qui fournissent ces autorisations.

Important

Parmi les autorisations exposées par le service cible, certaines ne sont peut-être pas nécessaires pour tous les contextes. Dans la mesure du possible, adhérez au principe du privilège minimum, en accordant à l’identité uniquement les privilèges nécessaires. Par exemple, si l’application a juste besoin de pouvoir lire à partir d’une source de données, utilisez un rôle qui a uniquement l’autorisation de lecture. Il serait inapproprié d’attribuer un rôle qui autorise aussi l’écriture dans ce service, car ce serait une autorisation excessive pour une opération de lecture. De même, vous voudrez vous assurer que l’attribution de rôle est limitée aux seules ressources qui doivent être lues.

Vous devez créer une attribution de rôle qui donne accès à votre rubrique Event Grid au moment de l’exécution. Les rôles de gestion comme Propriétaire ne sont pas suffisants. Le tableau suivant présente les rôles intégrés qui sont recommandés lors de l’utilisation de l’extension Event Hubs dans le cadre d’un fonctionnement normal. Votre application peut nécessiter des autorisations supplémentaires en fonction du code que vous écrivez.

Type de liaison Exemples de rôles intégrés
Liaison de sortie Contributeur EventGrid, expéditeur de données EventGrid

Étapes suivantes