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

Use a associação de saída 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 assinaturas de acesso compartilhado (SAS).

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

Importante

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

O Azure Functions dá suporte a dois modelos de programação para Python. A maneira como você define suas associações depende do modelo de programação escolhido.

O modelo de programação v2 do Python permite que você defina associações usando decoradores diretamente no código de função do Python. Para saber mais, confira o Guia do desenvolvedor do Python.

Este artigo dá suporte a ambos os modelos de programação.

Importante

A associação de saída da Grade de Eventos só está disponível para o Functions 2.x e superiores.

Exemplo

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

O exemplo a seguir mostra como o tipo personalizado é usado no gatilho e em uma associação de saída da 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 mostrará uma função Java que grava uma mensagem em um tópico personalizado da Grade de Eventos. A função usa o método setValue da associação para gerar uma cadeia de 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 disparada pelo 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 um cronômetro 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 da Grade de Eventos. A seção em que type é definido como eventGrid configura os valores necessários para estabelecer uma associação de saída da 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"
    }
  ]
}

Em sua função, use o Push-OutputBinding para enviar um evento a 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 associação de gatilho e uma função do Python que usa a associação. Em seguida, ele envia um evento ao tópico personalizado, conforme especificado pelo topicEndpointUri. O exemplo depende do modelo de programação v1 ou v2 do Python que você usa.

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# em processo e de processo de trabalho isolado usam atributos para configurar a associaçã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 do tópico.

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

Parâmetro Descrição
TopicEndpointUri O nome de uma configuração de aplicativo que contém o URI para o 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.
connection* 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 do tópico. Para obter mais informações sobre essas configurações, consulte Saída - configuração. Este é 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 objeto options transmitido para o método output.eventGrid().

Propriedade Descrição
topicEndpointUri O nome de uma configuração de aplicativo que contém o URI para o 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.
connection* O valor do prefixo comum para a configuração que contém o URI do ponto de extremidade do tópico. Ao definir a propriedade connection, as propriedades topicEndpointUri 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 que você define no arquivo function.json.

Propriedade function.json Descrição
tipo Deve ser definido como eventGrid.
direction Deve ser definido como out. Esse parâmetro é definido automaticamente quando você cria a associação no portal do Azure.
name É o nome da variável usada no código da função que representa o evento.
topicEndpointUri O nome de uma configuração de aplicativo que contém o URI para o 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.
connection* 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 você estiver desenvolvendo localmente, adicione as configurações do aplicativo no arquivo local.settings.json na coleção Values.

Importante

Verifique se você definiu o valor de TopicEndpointUri como o nome de uma configuração de 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 Connection.

Consulte a Seção de exemplo para obter exemplos completos.

Uso

Os tipos específicos com suporte pela associação de saída da Grade de Eventos dependem da versão de runtime do Functions, da versão do pacote de extensão e da modalidade de C# usada.

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

Type Descrição
string O evento como uma cadeia de caracteres.
byte[] Os bytes da mensagem de evento.
Tipos serializáveis JSON Um objeto que representa um evento JSON. O Functions tenta serializar um tipo de objeto CLR básico (POCO) em dados JSON.

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

Type Descrição
T[] em que 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 diretamente de Azure.Messaging.EventGrid.

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 cmdlet Push-OutputBinding para enviar um evento à associação de saída da Grade de Eventos.

Há duas opções para gerar uma mensagem da Grade de Eventos de uma função:

  • Valor retornado: definir a propriedade name no function.json para $return. Com essa configuração, o valor retornado da função será mantido como uma mensagem da Grade de Eventos.
  • Imperativo: passe um valor para definir o método do parâmetro declarado como um tipo de Saída. O valor passado para set será mantido como uma mensagem da Grade de Eventos.

conexões

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

Método de autenticação Descrição
Usar uma chave de tópico Defina as propriedades TopicEndpointUri e TopicKeySetting, conforme descrito em Usar uma chave de tópico.
Usar uma identidade Defina a propriedade Connection como o nome de um prefixo compartilhado para várias configurações do aplicativo, definindo em conjunto com uma autenticação baseada em identidade. Esse método tem suporte 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 do 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 propriedade TopicKeySetting 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 propriedade TopicEndpointUri da associação.

Autenticação baseada em identidade

Ao usar a versão 3.3.x ou superior da extensão, é possível se conectar a um tópico da Grade de Eventos usando uma identidade do Microsoft Entra para evitar a necessidade de 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 (nesse caso, myawesometopic) quando definir a propriedade Connection na associação.

Nesse modo, a extensão exige as seguintes propriedades:

Propriedade Modelo de variável de ambiente Descrição Valor de exemplo
URI do Ponto de Extremidade <CONNECTION_NAME_PREFIX>__topicEndpointUri O ponto de extremidade do tópico. https://<topic-name>.centralus-1.eventgrid.azure.net/api/events

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

Observação

Ao usar a Configuração de Aplicativos do Azure ou o Key Vault 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 : outras / no lugar de __ para garantir que os nomes sejam resolvidos corretamente.

Por exemplo, <CONNECTION_NAME_PREFIX>:topicEndpointUri.

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

Conceder permissão para a 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 será necessário atribuir uma função no Azure RBAC, usando as funções internas ou as personalizadas que fornecem essas permissões.

Importante

Algumas permissões que não são necessárias em todos os contextos podem ser expostas pelo serviço de destino. Sempre que possível, siga o princípio do privilégio mínimo, concedendo à identidade apenas os privilégios necessários. Por exemplo, se o aplicativo precisar apenas ser capaz de ler uma fonte de dados, use uma função que só tenha permissão de leitura. Seria inapropriado atribuir uma função que também permitisse a gravação nesse serviço, pois seria um excesso de permissões para uma operação de leitura. Da mesma forma, seria melhor garantir que a atribuição da função tivesse o escopo apenas sobre os recursos que precisam ser lidos.

Você deverá criar uma atribuição de função que forneça acesso ao sua Grade de Eventos em runtime. Funções de gerenciamento como Proprietário não são suficientes. A tabela a seguir mostra as funções internas recomendadas ao usar a extensão dos Hubs de Eventos em operação normal. Seu aplicativo pode exigir permissões adicionais com base no código escrito por você.

Tipo de associação Exemplo de funções internas
Associação de saída Colaborador da Grade de Eventos, Remetente de Dados da Grade de Eventos

Próximas etapas