Vinculação de saída da Grade de Eventos do Azure para o Azure Functions

Use a associação de saída Grade de Eventos para gravar eventos em um tópico personalizado. Você deve ter uma chave de acesso válida para o tópico personalizado. A associação de saída da Grade de Eventos não oferece suporte a tokens de assinatura de acesso compartilhado (SAS).

Para obter informações sobre detalhes de instalação e configuração, consulte Como trabalhar com gatilhos e associações de Grade de Eventos no Azure Functions.

Importante

Este artigo usa guias para oferecer suporte a várias versões do modelo de programação Node.js. O modelo v4 está geralmente disponível e foi projetado para ter uma experiência mais flexível e intuitiva para desenvolvedores JavaScript e TypeScript. Para obter mais detalhes sobre como o modelo v4 funciona, consulte o Guia do desenvolvedor do Azure Functions Node.js. Para saber mais sobre as diferenças entre v3 e v4, consulte o guia de migração.

O Azure Functions suporta dois modelos de programação para Python. A maneira como você define suas ligações depende do modelo de programação escolhido.

O modelo de programação Python v2 permite definir ligações usando decoradores diretamente em seu código de função Python. Para obter mais informações, consulte o guia do desenvolvedor do Python.

Este artigo suporta ambos os modelos de programação.

Importante

A ligação de saída da Grade de Eventos só está disponível para Funções 2.x e superiores.

Exemplo

O tipo do parâmetro de saída usado com uma ligação de saída de Grade de Eventos depende da versão de tempo de execução do Functions, da versão da extensão de vinculação e da modalidade da função C#. A função C# pode ser criada usando um dos seguintes modos C#:

  • Biblioteca de classes em processo: função C# compilada que é executada no mesmo processo que o tempo de execução do Functions.
  • Biblioteca de classes de processo de trabalho isolado: função C# compilada que é executada em um processo de trabalho isolado do tempo de execução.

O exemplo a seguir mostra como o tipo personalizado é usado no gatilho e em uma associação de saída de Grade de Eventos:

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

O exemplo a seguir mostra uma função Java que grava uma mensagem em um tópico personalizado da Grade de Eventos. A função usa o método da ligação para gerar uma cadeia de setValue caracteres.

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

Você também pode usar uma classe POJO para enviar mensagens da Grade de Eventos.

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

O exemplo a seguir mostra uma função TypeScript acionada por temporizador que gera um único evento:

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

Para gerar vários eventos, retorne uma matriz em vez de um único objeto. Por exemplo:

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

O exemplo a seguir mostra uma função JavaScript acionada por temporizador que gera um único evento:

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

Para gerar vários eventos, retorne uma matriz em vez de um único objeto. Por exemplo:

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

O exemplo a seguir demonstra como configurar uma função para gerar uma mensagem de evento Event Grid. A seção onde type está definida para eventGrid configurar os valores necessários para estabelecer uma ligação de saída de Grade de Eventos.

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

Na sua função, use o Push-OutputBinding para enviar um evento para um tópico personalizado por meio da associação de saída da Grade de Eventos.

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

O exemplo a seguir mostra uma ligação de gatilho e uma função Python que usa a ligação. Em seguida, ele envia um evento para o tópico personalizado, conforme especificado pelo topicEndpointUri. O exemplo depende se você usa o modelo de programação Python v1 ou v2.

Aqui está a função no arquivo 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"))

Atributos

As bibliotecas C# do processo de trabalho em processo e isoladas usam o atributo para configurar a ligação. Em vez disso, o script C# usa um arquivo de configuração function.json, conforme descrito no guia de script C#.

O construtor do atributo usa o nome de uma configuração de aplicativo que contém o nome do tópico personalizado e o nome de uma configuração de aplicativo que contém a chave de tópico.

A tabela a seguir explica os parâmetros para o EventGridOutputAttribute.

Parâmetro Description
TopicEndpointUri O nome de uma configuração de aplicativo que contém o URI do tópico personalizado, como MyTopicEndpointUri.
TopicKeySetting O nome de uma configuração de aplicativo que contém uma chave de acesso para o tópico personalizado.
conexão* O valor do prefixo comum para a configuração que contém o URI do ponto de extremidade do tópico. Para obter mais informações sobre o formato de nomenclatura dessa configuração de aplicativo, consulte Autenticação baseada em identidade.

Anotações

Para classes Java, use o atributo EventGridAttribute .

O construtor do atributo usa o nome de uma configuração de aplicativo que contém o nome do tópico personalizado e o nome de uma configuração de aplicativo que contém a chave de tópico. Para obter mais informações sobre essas configurações, consulte Saída - configuração. Aqui está um EventGridOutput exemplo de atributo:

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) {
            ...
    }
}

Configuração

A tabela a seguir explica as propriedades que você pode definir no options objeto passado para o output.eventGrid() método.

Property Description
tópicoEndpointUri O nome de uma configuração de aplicativo que contém o URI do tópico personalizado, como MyTopicEndpointUri.
topicKeySetting O nome de uma configuração de aplicativo que contém uma chave de acesso para o tópico personalizado.
conexão* O valor do prefixo comum para a configuração que contém o URI do ponto de extremidade do tópico. Ao definir a connection propriedade, as topicEndpointUri propriedades e topicKeySetting não devem ser definidas. Para obter mais informações sobre o formato de nomenclatura dessa configuração de aplicativo, consulte Autenticação baseada em identidade.

Configuração

A tabela a seguir explica as propriedades de configuração de associação definidas no arquivo function.json .

function.json propriedade Description
type Deve ser definido como eventGrid.
direção Deve ser definido como out. Esse parâmetro é definido automaticamente quando você cria a associação no portal do Azure.
Designação O nome da variável usada no código da função que representa o evento.
tópicoEndpointUri O nome de uma configuração de aplicativo que contém o URI do tópico personalizado, como MyTopicEndpointUri.
topicKeySetting O nome de uma configuração de aplicativo que contém uma chave de acesso para o tópico personalizado.
conexão* O valor do prefixo comum para a configuração que contém o URI do ponto de extremidade do tópico. Para obter mais informações sobre o formato de nomenclatura dessa configuração de aplicativo, consulte Autenticação baseada em identidade.

*O suporte para conexões baseadas em identidade requer a versão 3.3.x ou superior da extensão.

Quando estiver desenvolvendo localmente, adicione as configurações do aplicativo no arquivo local.settings.json na Values coleção.

Importante

Certifique-se de definir o valor de como o nome de uma configuração de TopicEndpointUri aplicativo que contém o URI do tópico personalizado. Não especifique o URI do tópico personalizado diretamente nesta propriedade. O mesmo se aplica ao usar Connectiono .

Consulte a seção Exemplo para obter exemplos completos.

Utilização

O tipo de parâmetro suportado pela ligação de saída da Grade de Eventos depende da versão de tempo de execução do Functions, da versão do pacote de extensão e da modalidade C# usada.

Quando você deseja que a função escreva um único evento, a associação de saída Grade de Eventos pode ser vinculada aos seguintes tipos:

Tipo Description
string O evento como uma cadeia de caracteres.
byte[] Os bytes da mensagem do evento.
Tipos serializáveis JSON Um objeto que representa um evento JSON. Functions tenta serializar um tipo de objeto CLR (POCO) simples em dados JSON.

Quando você deseja que a função escreva vários eventos, a associação de saída da Grade de Eventos pode ser vinculada aos seguintes tipos:

Tipo Description
T[] onde T é um dos tipos de evento único Uma matriz que contém vários eventos. Cada entrada representa um evento.

Para outros cenários de saída, crie e use tipos de Azure.Messaging.EventGrid diretamente.

Envie mensagens individuais chamando um parâmetro de método, como out EventGridOutput paramName, e escreva várias mensagens com ICollector<EventGridOutput>.

Acesse a mensagem de saída retornando o valor diretamente ou usando context.extraOutputs.set().

Acesse o evento de saída usando o Push-OutputBinding cmdlet para enviar um evento para a associação de saída da Grade de Eventos.

Há duas opções para enviar uma mensagem de grade de eventos de uma função:

  • Valor de retorno: defina a name propriedade em function.json como $return. Com essa configuração, o valor de retorno da função é mantido como uma mensagem de grade de eventos.
  • Imperativo: Passe um valor para o método set do parâmetro declarado como um tipo out . O valor passado para set é persistente como uma mensagem de Grade de Eventos.

Ligações

Há duas maneiras de autenticar em um tópico de Grade de Eventos ao usar a associação de saída de Grade de Eventos:

Método de autenticação Description
Usando uma chave de tópico Defina as TopicEndpointUri propriedades e TopicKeySetting , conforme descrito em Usar uma chave de tópico.
Usando uma identidade Defina a Connection propriedade como o nome de um prefixo compartilhado para várias configurações de aplicativo, definindo em conjunto a autenticação baseada em identidade. Este método é suportado ao usar a versão 3.3.x ou superior da extensão.

Usar uma chave de tópico

Use as seguintes etapas para configurar uma chave de tópico:

  1. Siga as etapas em Obter chaves de acesso para obter a chave de tópico para o tópico da Grade de Eventos.

  2. Nas configurações do aplicativo, crie uma configuração que defina o valor da chave do tópico. Use o nome dessa configuração para a TopicKeySetting propriedade da associação.

  3. Nas configurações do aplicativo, crie uma configuração que defina o ponto de extremidade do tópico. Use o nome dessa configuração para a TopicEndpointUri propriedade da associação.

Autenticação baseada em identidade

Ao usar a versão 3.3.x ou superior da extensão, você pode se conectar a um tópico da Grade de Eventos usando uma identidade do Microsoft Entra para evitar ter que obter e trabalhar com chaves de tópico.

Você precisa criar uma configuração de aplicativo que retorne o URI do ponto de extremidade do tópico. O nome da configuração deve combinar um prefixo comum exclusivo (por exemplo, myawesometopic) com o valor __topicEndpointUri. Em seguida, você deve usar esse prefixo comum (neste caso, myawesometopic) ao definir a Connection propriedade na associação.

Neste modo, a extensão requer as seguintes propriedades:

Property Modelo de variável de ambiente Description Valor de exemplo
URI do ponto de extremidade do tópico <CONNECTION_NAME_PREFIX>__topicEndpointUri O ponto final do tópico. https://<topic-name>.centralus-1.eventgrid.azure.net/api/events

Mais propriedades podem ser usadas para personalizar a conexão. Consulte Propriedades comuns para conexões baseadas em identidade.

Nota

Ao usar a Configuração do Aplicativo do Azure ou o Cofre da Chave para fornecer configurações para conexões baseadas em identidade gerenciada, os nomes de configuração devem usar um separador de chave válido, como : ou / no lugar do para garantir que os __ nomes sejam resolvidos corretamente.

Por exemplo, <CONNECTION_NAME_PREFIX>:topicEndpointUri.

Quando hospedadas no serviço Azure Functions, as conexões baseadas em identidade usam uma identidade gerenciada. A identidade atribuída ao sistema é usada por padrão, embora uma identidade atribuída ao usuário possa ser especificada com as credential propriedades e clientID . Observe que nãosuporte para a configuração de uma identidade atribuída pelo usuário com uma ID de recurso. Quando executado em outros contextos, como desenvolvimento local, sua identidade de desenvolvedor é usada, embora isso possa ser personalizado. Consulte Desenvolvimento local com conexões baseadas em identidade.

Conceder permissão à identidade

Qualquer identidade que esteja sendo usada deve ter permissões para executar as ações pretendidas. Para a maioria dos serviços do Azure, isso significa que você precisa atribuir uma função no RBAC do Azure, usando funções internas ou personalizadas que fornecem essas permissões.

Importante

Algumas permissões podem ser expostas pelo serviço de destino que não são necessárias para todos os contextos. Sempre que possível, aderir ao princípio do menor privilégio, concedendo à identidade apenas os privilégios necessários. Por exemplo, se o aplicativo só precisa ser capaz de ler de uma fonte de dados, use uma função que só tenha permissão para ler. Seria inadequado atribuir uma função que também permita escrever a esse serviço, pois isso seria uma permissão excessiva para uma operação de leitura. Da mesma forma, convém garantir que a atribuição de função tenha escopo apenas sobre os recursos que precisam ser lidos.

Você deve criar uma atribuição de função que forneça acesso ao tópico da Grade de Eventos em tempo de execução. Funções de gestão como Proprietário não são suficientes. A tabela a seguir mostra as funções internas recomendadas ao usar a extensão Hubs de Eventos em operação normal. Seu aplicativo pode exigir permissões adicionais com base no código que você escreve.

Tipo de vinculação Exemplo de funções internas
Vinculação de saída EventGrid Contributor, EventGrid Data Sender

Próximos passos