Azure Event Grid-Ausgabebindung für Azure Functions

Verwenden Sie die Event Grid-Ausgabebindung, um Ereignisse in ein benutzerdefiniertes Thema zu schreiben. Sie müssen einen gültigen Zugriffsschlüssel für das benutzerdefinierte Thema besitzen. Die Event Grid-Ausgabebindung unterstützt keine SAS-Token (Shared Access Signature).

Informationen zu Setup- und Konfigurationsdetails finden Sie unter How to work with Event Grid triggers and bindings in Azure Functions (Verwenden von Event Grid-Triggern und -Bindungen in Azure Functions).

Wichtig

In diesem Artikel werden Registerkarten verwendet, um mehrere Versionen des Node.js-Programmiermodells zu unterstützen. Das v4-Modell ist allgemein verfügbar und bietet JavaScript- und TypeScript-Entwicklern eine flexiblere und intuitivere Erfahrung. Weitere Informationen zur Funktionsweise des v4-Modells finden Sie im Azure Functions Node.js-Entwicklerhandbuch. Weitere Informationen zu den Unterschieden zwischen v3 und v4 finden Sie im Migrationshandbuch.

Azure Functions unterstützt zwei Programmiermodelle für Python. Wie Sie Ihre Bindung definieren, hängt vom gewählten Python-Programmiermodell ab.

Mit dem Python v2-Programmiermodell können Sie Bindungen mithilfe von Decorators direkt im Python-Funktionscode definieren. Weitere Informationen finden Sie im Python Developer-Leitfaden.

In diesem Artikel werden beide Programmiermodelle unterstützt.

Wichtig

Die Event Grid-Ausgabebindung ist nur für Functions 2. x und höher verfügbar.

Beispiel

Welcher Typ von Ausgabeparameter mit einer Event Grid-Ausgabebindung verwendet wird, hängt von der Functions-Runtimeversion, der Bindungserweiterungsversion und der Modalität der C#-Funktion ab. Die C#-Funktion kann mit einem der folgenden C#-Modi erstellt werden:

Das folgende Beispiel zeigt, wie der benutzerdefinierte Typ sowohl im Trigger als auch in einer Event Grid-Ausgabebindung verwendet wird:

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; }
    }
}

Das folgende Beispiel zeigt eine Java-Funktion, die eine Nachricht in ein benutzerdefiniertes Event Hub-Thema schreibt. Die Funktion verwendet die setValue-Methode der Bindung, um eine Zeichenfolge auszugeben.

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);
    }
}

Sie können auch eine POJO-Klasse verwenden, um Event Grid-Nachrichten zu senden.

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;
    }  
}

Das folgende Beispiel zeigt eine durch einen Timer ausgelöste TypeScript-Funktion, die ein einzelnes Ereignis ausgibt:

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,
});

Um mehrere Ereignisse auszugeben, geben Sie anstelle eines einzelnen Objekts ein Array zurück. Beispiel:

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,
    },
];

Das folgende Beispiel zeigt eine durch einen Timer ausgelöste JavaScript-Funktion, die ein einzelnes Ereignis ausgibt:

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,
        };
    },
});

Um mehrere Ereignisse auszugeben, geben Sie anstelle eines einzelnen Objekts ein Array zurück. Beispiel:

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,
    },
];

Im folgenden Beispiel wird veranschaulicht, wie Sie eine Funktion so konfigurieren, dass eine Event Grid-Ereignismeldung ausgegeben wird. Der Abschnitt, in dem type auf eventGrid festgelegt ist, konfiguriert die Werte, die zum Einrichten einer Event Grid-Ausgabebindung erforderlich sind.

{
  "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"
    }
  ]
}

Verwenden Sie in Ihrer Funktion Push-OutputBinding, um ein Ereignis über die Event Grid-Ausgabebindung an ein benutzerdefiniertes Thema zu senden.

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"
})

Das folgende Beispiel zeigt eine Triggerbindung sowie eine Python-Funktion, die die Bindung verwendet. Anschließend sendet sie ein Ereignis an das benutzerdefinierte Thema, wie durch topicEndpointUri angegeben. Das Beispiel hängt davon ab, ob Sie das Python-Programmiermodell v1 oder v2 verwenden.

Dies ist die Funktion in der Datei „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"))

Attributes

Von C#-Bibliotheken vom Typ prozessintern und isolierter Workerprozess wird ein Attribut verwendet, um die Bindung zu definieren. Das C#-Skript verwendet stattdessen eine Konfigurationsdatei function.json, wie im C#-Skript-Handbuch beschrieben.

Der Konstruktor des Attributs verwendet den Namen einer Anwendungseinstellung an, die den Namen des benutzerdefinierten Themas enthält, sowie den Namen einer Anwendungseinstellung, die den Themenschlüssel enthält.

In der folgenden Tabelle werden die Parameter für EventGridOutputAttribute erläutert.

Parameter BESCHREIBUNG
TopicEndpointUri Der Name einer App-Einstellung, die den URI für das benutzerdefinierte Thema enthält, z. B. MyTopicEndpointUri.
TopicKeySetting Der Name einer App-Einstellung, die einen Zugriffsschlüssel für das benutzerdefinierte Thema enthält.
Verbindung* Der Wert des allgemeinen Präfixes für die Einstellung, die den Themenendpunkt-URI enthält. Weitere Informationen zum Benennungsformat dieser Anwendungseinstellung finden Sie unter Identitätsbasierte Authentifizierung.

Anmerkungen

Verwenden Sie für Java-Klassen das EventGridAttribute-Attribut.

Der Konstruktor des Attributs nimmt den Namen einer App-Einstellung an, die den Namen des benutzerdefinierten Themas enthält, sowie den Namen einer App-Einstellung, die den Themenschlüssel enthält. Weitere Informationen zu diesen Einstellungen finden Sie unter Ausgabe: Konfiguration. Dieses Beispiel zeigt ein 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) {
            ...
    }
}

Konfiguration

In der folgenden Tabelle werden die Eigenschaften erläutert, die Sie für das options-Objekt festlegen können, das an die output.eventGrid()-Methode übergeben wurde.

Eigenschaft Beschreibung
topicEndpointUri Der Name einer App-Einstellung, die den URI für das benutzerdefinierte Thema enthält, z. B. MyTopicEndpointUri.
topicKeySetting Der Name einer App-Einstellung, die einen Zugriffsschlüssel für das benutzerdefinierte Thema enthält.
Verbindung* Der Wert des allgemeinen Präfixes für die Einstellung, die den Themenendpunkt-URI enthält. Beim Festlegen der Eigenschaft connection sollten die Eigenschaften topicEndpointUri und topicKeySetting nicht festgelegt werden. Weitere Informationen zum Benennungsformat dieser Anwendungseinstellung finden Sie unter Identitätsbasierte Authentifizierung.

Konfiguration

Die folgende Tabelle gibt Aufschluss über die Bindungskonfigurationseigenschaften, die Sie in der Datei function.json festlegen.

function.json-Eigenschaft BESCHREIBUNG
type Muss auf eventGrid festgelegt sein.
direction Muss auf out festgelegt sein. Dieser Parameter wird automatisch festgelegt, wenn Sie die Bindung im Azure Portal erstellen.
name Der Variablenname, der in Funktionscode verwendet wird, der das Ereignis darstellt.
topicEndpointUri Der Name einer App-Einstellung, die den URI für das benutzerdefinierte Thema enthält, z. B. MyTopicEndpointUri.
topicKeySetting Der Name einer App-Einstellung, die einen Zugriffsschlüssel für das benutzerdefinierte Thema enthält.
Verbindung* Der Wert des allgemeinen Präfixes für die Einstellung, die den Themenendpunkt-URI enthält. Weitere Informationen zum Benennungsformat dieser Anwendungseinstellung finden Sie unter Identitätsbasierte Authentifizierung.

*Die Unterstützung für identitätsbasierte Verbindungen erfordert Version 3.3.x oder höher der Erweiterung.

Wenn Sie die Entwicklung lokal ausführen, fügen Sie Ihre Anwendungseinstellungen in der Datei local.settings.json in der Values-Sammlung hinzu.

Wichtig

Stellen Sie sicher, dass Sie den Wert von TopicEndpointUri auf den Namen einer App-Einstellung festlegen, die den URI des benutzerdefinierten Themas enthält. Geben Sie den URI des benutzerdefinierten Themas nicht direkt in dieser Eigenschaft an. Dasselbe gilt, wenn Connection verwendet wird.

Vollständige Beispiele finden Sie im Abschnitt Beispiele.

Verwendung

Der von der Event Grid-Ausgabebindung unterstützte Parametertyp hängt von der Functions-Runtimeversion, von der Version des Erweiterungspakets sowie von der verwendeten C#-Modalität ab.

Wenn die Funktion ein einzelnes Ereignis schreiben soll, kann die Event Grid-Ausgabebindung an die folgenden Typen gebunden werden:

type BESCHREIBUNG
string Das Ereignis als Zeichenfolge.
byte[] Die Bytes der Ereignisnachricht.
Serialisierbare JSON-Typen Ein Objekt, das ein JSON-Ereignis darstellt. Functions versucht, einen POCO-Typ (Plain-Old CLR Object) in JSON-Daten zu serialisieren.

Wenn die Funktion mehrere Ereignisse schreiben soll, kann die Event Grid-Ausgabebindung an die folgenden Typen gebunden werden:

type BESCHREIBUNG
T[], wobei T einer der einzelnen Ereignistypen ist Ein Array, das mehrere Ereignisse enthält. Jeder Eintrag stellt ein Ereignis dar.

Für andere Ausgabeszenarien erstellen und verwenden Sie Typen direkt aus Azure.Messaging.EventGrid.

Senden Sie einzelne Nachrichten durch Aufrufen eines Methodenparameters wie out EventGridOutput paramName, und schreiben Sie mehrere Nachrichten mit ICollector<EventGridOutput>.

Auf die Ausgabemeldung greifen Sie zu, indem Sie den Wert direkt zurückgeben oder context.extraOutputs.set() verwenden.

Greifen Sie mithilfe des Cmdlets Push-OutputBinding auf das Ausgabeereignis zu, um ein Ereignis an die Event Grid-Ausgabebindung zu senden.

Es gibt zwei Optionen für das Ausgeben einer Event Hub-Nachricht aus einer Funktion:

  • Rückgabewert: Legen Sie die Eigenschaft name in function.json auf $return fest. Mit dieser Konfiguration wird der Rückgabewert der Funktion als Event Grid-Nachricht beibehalten.
  • Imperativ: Übergeben Sie einen Wert an die set-Methode des Parameters, der als Out-Typ deklariert ist. Der an set übergebene Wert wird als Event Grid-Nachricht beibehalten.

Verbindungen

Es gibt zwei Möglichkeiten, sich bei einem Event Grid-Thema zu authentifizieren, wenn Sie die Event Grid-Ausgabebindung verwenden:

Authentifizierungsmethode Beschreibung
Verwenden eines Themenschlüssels Legen Sie die Eigenschaften TopicEndpointUri und TopicKeySetting fest, wie unter Verwenden eines Themenschlüssels beschrieben.
Verwenden einer Identität Setzen Sie die Eigenschaft Connection auf den Namen eines gemeinsamen Präfixes für mehrere Anwendungseinstellungen, die zusammen eine identitätsbasierte Authentifizierung definieren. Diese Methode wird unterstützt, wenn Version 3.3.x oder höher der Erweiterung verwendet wird.

Verwenden Sie einen Themenschlüssel

Führen Sie die folgenden Schritte aus, um einen Themenschlüssel zu konfigurieren:

  1. Führen Sie die Schritte unter Abrufen von Zugriffsschlüsseln aus, um den Themenschlüssel für Ihr Event Grid-Thema zu erhalten.

  2. Erstellen Sie in Ihren Anwendungseinstellungen eine Einstellung, die den Wert des Themenschlüssels definiert. Verwenden Sie den Namen dieser Einstellung für die TopicKeySetting-Eigenschaft der Bindung.

  3. Erstellen Sie in Ihren Anwendungseinstellungen eine Einstellung, die den Wert des Themenendpunkts definiert. Verwenden Sie den Namen dieser Einstellung für die TopicEndpointUri-Eigenschaft der Bindung.

Identitätsbasierte Authentifizierung

Wenn Sie Version 3.3.x oder höher der Erweiterung verwenden, können Sie mithilfe einer Microsoft Entra-Identität eine Verbindung mit einem Event Grid-Thema herstellen, um zu vermeiden, dass Sie Themenschlüssel abrufen und damit arbeiten müssen.

Sie müssen eine Anwendungseinstellung erstellen, die den Themenendpunkt-URI zurückgibt. Der Name der Einstellung sollte ein eindeutiges allgemeines Präfix (z. B. myawesometopic) mit dem Wert __topicEndpointUri kombinieren. Anschließend müssen Sie dieses allgemeine Präfix (in diesem Fall myawesometopic) verwenden, wenn Sie die Eigenschaft Connection in der Bindung definieren.

In diesem Modus benötigt die Erweiterung die folgenden Eigenschaften:

Eigenschaft Vorlage für Umgebungsvariable BESCHREIBUNG Beispielwert
Themenendpunkt-URI <CONNECTION_NAME_PREFIX>__topicEndpointUri Der Themenendpunkt. https://<topic-name>.centralus-1.eventgrid.azure.net/api/events

Weitere Eigenschaften können verwendet werden, um die Verbindung anzupassen. Weitere Informationen finden Sie unter Allgemeine Eigenschaften für identitätsbasierte Verbindungen.

Hinweis

Wenn Sie Azure App Configuration oder Key Vault verwenden, um Einstellungen für verwaltete identitätsbasierte Verbindungen bereitzustellen, sollten Sie für Einstellungsnamen ein gültiges Schlüsseltrennzeichen wie z. B. : oder / anstelle von __ verwenden, um sicherzustellen, dass Namen ordnungsgemäß aufgelöst werden.

Beispiel: <CONNECTION_NAME_PREFIX>:topicEndpointUri.

Identitätsbasierte Verbindungen verwenden eine verwaltete Identität, wenn sie im Azure Functions-Dienst gehostet werden. Standardmäßig wird eine vom System zugewiesene Identität verwendet, auch wenn mit den Eigenschaften credential und clientID eine vom Benutzer zugewiesene Identität angegeben werden kann. Beachten Sie, dass das Konfigurieren einer benutzerseitig zugewiesenen Identität mit einer Ressourcen-ID nicht unterstützt wird. Bei Ausführung in anderen Kontexten (z. B. bei der lokalen Entwicklung) wird stattdessen Ihre Entwickleridentität verwendet, Dieses Verhalten kann angepasst werden. Weitere Informationen finden Sie unter Lokale Entwicklung mit identitätsbasierten Verbindungen.

Erteilen der Berechtigung für die Identität

Unabhängig davon, welche Identität verwendet wird, muss diese über Berechtigungen zum Ausführen der vorgesehenen Aktionen verfügen. Daher müssen Sie für die meisten Azure-Dienste eine Rolle in Azure RBAC zuweisen, indem Sie entweder integrierte oder benutzerdefinierte Rollen verwenden, die diese Berechtigungen bieten.

Wichtig

Vom Zieldienst werden möglicherweise einige nicht für alle Kontexte erforderliche Berechtigungen verfügbar gemacht. Befolgen Sie nach Möglichkeit das Prinzip der geringsten Berechtigung, und gewähren Sie der Identität nur die erforderlichen Berechtigungen. Wenn die App beispielsweise nur Daten aus einer Datenquelle lesen muss, verwenden Sie eine Rolle, die nur über Leseberechtigungen verfügt. Es wäre nicht angemessen, eine Rolle zu zuweisen, die auch das Schreiben in diesen Dienst zulässt, da dies eine übermäßige Berechtigung für einen Lesevorgang wäre. Ebenso sollten Sie sicherstellen, dass die Rollenzuweisung auf die Ressourcen begrenzt ist, die gelesen werden müssen.

Sie müssen eine Rollenzuweisung erstellen, die zur Laufzeit Zugriff auf Ihr Event Grid-Thema ermöglicht. Verwaltungsrollen wie Besitzer sind nicht ausreichend. Die folgende Tabelle zeigt integrierte Rollen, die für die Event Hubs-Erweiterung im Normalbetrieb empfohlen werden. Ihre Anwendung erfordert möglicherweise zusätzliche Berechtigungen basierend auf dem von Ihnen geschriebenen Code.

Bindungstyp Integrierte Beispielrollen
Ausgabebindung EventGrid-Mitwirkender, EventGrid-Datensender

Nächste Schritte