Compartilhar via


Grade de Eventos do Azure biblioteca de clientes para .NET – versão 4.20.0

A Grade de Eventos do Azure permite compilar facilmente aplicativos com as arquiteturas baseadas em evento. O serviço grade de eventos gerencia totalmente todo o roteamento de eventos de qualquer origem, para qualquer destino, para qualquer aplicativo. Eventos de serviço do Azure e eventos personalizados podem ser publicados diretamente no serviço, onde os eventos podem ser filtrados e enviados para vários destinatários, como manipuladores internos ou webhooks personalizados. Para saber mais sobre Grade de Eventos do Azure: O que é a Grade de Eventos?

Use a biblioteca de clientes para Grade de Eventos do Azure para:

Introdução

Instalar o pacote

Instale a biblioteca de clientes do NuGet:

dotnet add package Azure.Messaging.EventGrid

Pré-requisitos

Você deve ter uma assinatura do Azure e um grupo de recursos do Azure com um tópico ou domínio personalizado da Grade de Eventos. Siga este tutorial passo a passo para registrar o provedor de recursos da Grade de Eventos e criar tópicos da Grade de Eventos usando o portal do Azure. Há um tutorial semelhante usando a CLI do Azure.

Autenticar o Cliente

Para que a biblioteca de clientes interaja com um tópico ou domínio, você precisará do endpoint tópico da Grade de Eventos e de um credential, que pode ser criado usando a chave de acesso do tópico.

Você pode encontrar o ponto de extremidade do tópico da Grade de Eventos no Portal do Azure ou usando o snippet da CLI do Azure abaixo.

az eventgrid topic show --name <your-resource-name> --resource-group <your-resource-group-name> --query "endpoint"

A chave de acesso também pode ser encontrada por meio do portal ou usando o snippet da CLI do Azure abaixo:

az eventgrid topic key list --name <your-resource-name> --resource-group <your-resource-group-name> --query "key1"

Autenticar usando a chave de acesso do tópico

Depois de ter a chave de acesso e o ponto de extremidade do tópico, você poderá criar o cliente do publicador da seguinte maneira:

EventGridPublisherClient client = new EventGridPublisherClient(
    new Uri("<endpoint>"),
    new AzureKeyCredential("<access-key>"));

Autenticar usando a Assinatura de Acesso Compartilhado

A Grade de Eventos também dá suporte à autenticação com uma assinatura de acesso compartilhado que permite fornecer acesso a um recurso que expira por um determinado tempo sem compartilhar sua chave de acesso. Em geral, o fluxo de trabalho seria que um aplicativo geraria a cadeia de caracteres SAS e entregaria a cadeia de caracteres para outro aplicativo que consumiria a cadeia de caracteres. Gere a SAS:

var builder = new EventGridSasBuilder(new Uri(topicEndpoint), DateTimeOffset.Now.AddHours(1));
var keyCredential = new AzureKeyCredential(topicAccessKey);
string sasToken = builder.GenerateSas(keyCredential);

Veja como ele seria usado da perspectiva do consumidor:

var sasCredential = new AzureSasCredential(sasToken);
EventGridPublisherClient client = new EventGridPublisherClient(
    new Uri(topicEndpoint),
    sasCredential);

EventGridPublisherClient também aceita um conjunto de opções de configuração por meio EventGridPublisherClientOptionsde . Por exemplo, você pode especificar um serializador personalizado que será usado para serializar os dados de evento para JSON.

Autenticar usando o Azure Active Directory

Grade de Eventos do Azure fornece integração com o Azure Active Directory (Azure AD) para autenticação baseada em identidade de solicitações. Com Azure AD, você pode usar o RBAC (controle de acesso baseado em função) para conceder acesso aos recursos de Grade de Eventos do Azure a usuários, grupos ou aplicativos. A biblioteca de Identidade do Azure fornece suporte fácil ao Azure Active Directory para autenticação.

Para enviar eventos para um tópico ou domínio usando o Azure Active Directory, a identidade autenticada deve ter a função "EventGrid Data Sender" atribuída.

EventGridPublisherClient client = new EventGridPublisherClient(
    new Uri(topicEndpoint),
    new DefaultAzureCredential());

Principais conceitos

Para obter informações sobre conceitos gerais da Grade de Eventos: Conceitos em Grade de Eventos do Azure.

EventGridPublisherClient

Um editor envia eventos para o serviço da Grade de Eventos. A Microsoft publica os eventos para vários serviços do Azure. Você pode publicar eventos de seu próprio aplicativo usando o EventGridPublisherClient.

Esquemas de evento

Um evento é a menor quantidade de informações que descreve totalmente algo que aconteceu no sistema. A Grade de Eventos dá suporte a vários esquemas para eventos de codificação. Quando um tópico ou domínio personalizado é criado, você especifica o esquema que será usado ao publicar eventos.

Esquema da Grade de Eventos

Embora você possa configurar seu tópico para usar um esquema personalizado, é mais comum usar o esquema da Grade de Eventos já definido. Consulte as especificações e os requisitos aqui.

Esquema do CloudEvents v 1.0

Outra opção é usar o esquema CloudEvents v1.0. CloudEvents é um projeto da Cloud Native Computing Foundation que produz uma especificação para descrever dados de evento de maneira comum. O resumo do serviço de CloudEvents pode ser encontrado aqui.

Independentemente do esquema que seu tópico ou domínio está configurado para usar, EventGridPublisherClient será usado para publicar eventos nele. Use o SendEvents método ou SendEventsAsync para publicação.

Entrega de eventos

Os eventos entregues aos consumidores pela Grade de Eventos são entregues como JSON. Dependendo do tipo de consumidor que está sendo entregue, o serviço da Grade de Eventos pode fornecer um ou mais eventos como parte de uma única carga. A manipulação de eventos será diferente com base em qual esquema o evento foi entregue. No entanto, o padrão geral permanecerá o mesmo:

  • Analise eventos de JSON em eventos individuais. Com base no esquema de evento (Grade de Eventos ou CloudEvents), agora você pode acessar informações básicas sobre o evento no envelope (propriedades que estão presentes para todos os eventos, como hora e tipo de evento).
  • Desserialize os dados do evento. Dado um EventGridEvent ou CloudEvent, o usuário pode tentar acessar o conteúdo do evento, ou dados, desserializando para um tipo específico. Você pode fornecer um serializador personalizado neste ponto para decodificar corretamente os dados.

Acesso thread-safe

Garantimos que todos os métodos de instância do cliente sejam thread-safe e independentes uns dos outros (diretriz). Isso garante que a recomendação de reutilize instâncias de cliente seja sempre segura, mesmo entre threads.

Conceitos adicionais

Opções do | clienteAcessando a resposta | Operações de execução longa | Tratamento de falhas | Diagnostics | Zombando | Tempo de vida do cliente

Exemplos

Publicar eventos da Grade de Eventos em um Tópico da Grade de Eventos

A publicação de eventos na Grade de Eventos é executada usando o EventGridPublisherClient. Use o método fornecido SendEvent/SendEventAsync para publicar um único evento no tópico.

// Add EventGridEvents to a list to publish to the topic
EventGridEvent egEvent =
    new EventGridEvent(
        "ExampleEventSubject",
        "Example.EventType",
        "1.0",
        "This is the event data");

// Send the event
await client.SendEventAsync(egEvent);

Para publicar um lote de eventos, use o SendEvents/SendEventsAsync método .

// Example of a custom ObjectSerializer used to serialize the event payload to JSON
var myCustomDataSerializer = new JsonObjectSerializer(
    new JsonSerializerOptions()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    });

// Add EventGridEvents to a list to publish to the topic
List<EventGridEvent> eventsList = new List<EventGridEvent>
{
    // EventGridEvent with custom model serialized to JSON
    new EventGridEvent(
        "ExampleEventSubject",
        "Example.EventType",
        "1.0",
        new CustomModel() { A = 5, B = true }),

    // EventGridEvent with custom model serialized to JSON using a custom serializer
    new EventGridEvent(
        "ExampleEventSubject",
        "Example.EventType",
        "1.0",
        myCustomDataSerializer.Serialize(new CustomModel() { A = 5, B = true })),
};

// Send the events
await client.SendEventsAsync(eventsList);

Publicar CloudEvents em um tópico da Grade de Eventos

A publicação de eventos na Grade de Eventos é executada usando o EventGridPublisherClient. Use o método fornecido SendEvents/SendEventsAsync para publicar eventos no tópico.

// Example of a custom ObjectSerializer used to serialize the event payload to JSON
var myCustomDataSerializer = new JsonObjectSerializer(
    new JsonSerializerOptions()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    });

// Add CloudEvents to a list to publish to the topic
List<CloudEvent> eventsList = new List<CloudEvent>
{
    // CloudEvent with custom model serialized to JSON
    new CloudEvent(
        "/cloudevents/example/source",
        "Example.EventType",
        new CustomModel() { A = 5, B = true }),

    // CloudEvent with custom model serialized to JSON using a custom serializer
    new CloudEvent(
        "/cloudevents/example/source",
        "Example.EventType",
        myCustomDataSerializer.Serialize(new CustomModel() { A = 5, B = true }),
        "application/json"),

    // CloudEvents also supports sending binary-valued data
    new CloudEvent(
        "/cloudevents/example/binarydata",
        "Example.EventType",
        new BinaryData(Encoding.UTF8.GetBytes("This is treated as binary data")),
        "application/octet-stream")};

// Send the events
await client.SendEventsAsync(eventsList);

Publicar eventos da Grade de Eventos em um domínio da Grade de Eventos

Um domínio de evento é uma ferramenta de gerenciamento para um grande número de tópicos da Grade de Eventos relacionados ao mesmo aplicativo. Você pode pensar nisso como um meta-tópico que pode ter milhares de tópicos individuais. Quando você cria um domínio de evento, recebe um ponto de extremidade de publicação semelhante a se você criou um tópico na Grade de Eventos.

Para publicar eventos em qualquer tópico em um Domínio de Evento, envie os eventos por push para o ponto de extremidade do domínio da mesma maneira que faria para um tópico personalizado. A única diferença é que você deve especificar o tópico para o qual você gostaria que o evento seja entregue.

// Add EventGridEvents to a list to publish to the domain
// Don't forget to specify the topic you want the event to be delivered to!
List<EventGridEvent> eventsList = new List<EventGridEvent>
{
    new EventGridEvent(
        "ExampleEventSubject",
        "Example.EventType",
        "1.0",
        "This is the event data")
    {
        Topic = "MyTopic"
    }
};

// Send the events
await client.SendEventsAsync(eventsList);

Para enviar CloudEvents, a fonte CloudEvent é usada como o tópico de domínio:

List<CloudEvent> eventsList = new List<CloudEvent>();

for (int i = 0; i < 10; i++)
{
    CloudEvent cloudEvent = new CloudEvent(
        // the source is mapped to the domain topic
        $"Subject-{i}",
        "Microsoft.MockPublisher.TestEvent",
        "hello")
    {
        Id = $"event-{i}",
        Time = DateTimeOffset.Now
    };
    eventsList.Add(cloudEvent);
}

await client.SendEventsAsync(eventsList);

Recebendo e desserializando eventos

Há vários serviços diferentes do Azure que atuam como manipuladores de eventos.

Observação: se estiver usando Webhooks para entrega de eventos do esquema da Grade de Eventos, a Grade de Eventos exigirá que você prove a propriedade do ponto de extremidade do Webhook antes de começar a entregar eventos para esse ponto de extremidade. No momento da criação da assinatura do evento, a Grade de Eventos envia um evento de validação de assinatura para o ponto de extremidade, conforme visto abaixo. Saiba mais sobre como concluir o handshake aqui: Entrega de eventos de webhook. Para o esquema CloudEvents, o serviço valida a conexão usando o método de opções HTTP. Saiba mais aqui: Validação do CloudEvents.

Depois que os eventos são entregues ao manipulador de eventos, podemos desserializar o conteúdo JSON em uma lista de eventos.

Usando EventGridEvent:

// Parse the JSON payload into a list of events
EventGridEvent[] egEvents = EventGridEvent.ParseMany(BinaryData.FromStream(httpContent));

Usando CloudEvent:

var bytes = await httpContent.ReadAsByteArrayAsync();
// Parse the JSON payload into a list of events
CloudEvent[] cloudEvents = CloudEvent.ParseMany(new BinaryData(bytes));

Desserializando dados de evento

A partir daqui, é possível acessar os dados do evento desserializando para um tipo específico chamando ToObjectFromJson<T>() na Data propriedade . Para desserializar para o tipo correto, a EventType propriedade (Type para CloudEvents) ajuda a distinguir entre eventos diferentes. Os dados de evento personalizados devem ser desserializados usando o método ToObjectFromJson<T>()genérico . Há também um método ToObject<T>() de extensão que aceita um personalizado ObjectSerializer para desserializar os dados do evento.

foreach (CloudEvent cloudEvent in cloudEvents)
{
    switch (cloudEvent.Type)
    {
        case "Contoso.Items.ItemReceived":
            // By default, ToObjectFromJson<T> uses System.Text.Json to deserialize the payload
            ContosoItemReceivedEventData itemReceived = cloudEvent.Data.ToObjectFromJson<ContosoItemReceivedEventData>();
            Console.WriteLine(itemReceived.ItemSku);
            break;
        case "MyApp.Models.CustomEventType":
            // One can also specify a custom ObjectSerializer as needed to deserialize the payload correctly
            TestPayload testPayload = cloudEvent.Data.ToObject<TestPayload>(myCustomSerializer);
            Console.WriteLine(testPayload.Name);
            break;
        case SystemEventNames.StorageBlobDeleted:
            // Example for deserializing system events using ToObjectFromJson<T>
            StorageBlobDeletedEventData blobDeleted = cloudEvent.Data.ToObjectFromJson<StorageBlobDeletedEventData>();
            Console.WriteLine(blobDeleted.BlobType);
            break;
    }
}

Usando TryGetSystemEventData():

Se estiver esperando principalmente eventos do sistema, talvez seja mais limpo ativar TryGetSystemEventData() e usar a correspondência de padrões para agir nos eventos individuais. Se um evento não for um evento do sistema, o método retornará false e o parâmetro out será nulo.

Como uma ressalva, se você estiver usando um tipo de evento personalizado com um valor EventType que posteriormente será adicionado como um evento do sistema pelo serviço e pelo SDK, o valor retornado de alterará de TryGetSystemEventDatafalse para true. Isso pode surgir se você estiver criando preventivamente seus próprios eventos personalizados para eventos que já estão sendo enviados pelo serviço, mas ainda não foram adicionados ao SDK. Nesse caso, é melhor usar o método genérico ToObjectFromJson<T> na propriedade para que o Data fluxo de código não seja alterado automaticamente após a atualização (é claro, talvez você ainda queira modificar seu código para consumir o modelo de evento do sistema recém-lançado em vez do modelo personalizado).

foreach (EventGridEvent egEvent in egEvents)
{
    // If the event is a system event, TryGetSystemEventData will return the deserialized system event
    if (egEvent.TryGetSystemEventData(out object systemEvent))
    {
        switch (systemEvent)
        {
            case SubscriptionValidationEventData subscriptionValidated:
                Console.WriteLine(subscriptionValidated.ValidationCode);
                break;
            case StorageBlobCreatedEventData blobCreated:
                Console.WriteLine(blobCreated.BlobType);
                break;
            // Handle any other system event type
            default:
                Console.WriteLine(egEvent.EventType);
                // we can get the raw Json for the event using Data
                Console.WriteLine(egEvent.Data.ToString());
                break;
        }
    }
    else
    {
        switch (egEvent.EventType)
        {
            case "MyApp.Models.CustomEventType":
                TestPayload deserializedEventData = egEvent.Data.ToObjectFromJson<TestPayload>();
                Console.WriteLine(deserializedEventData.Name);
                break;
            // Handle any other custom event type
            default:
                Console.Write(egEvent.EventType);
                Console.WriteLine(egEvent.Data.ToString());
                break;
        }
    }
}

Solução de problemas

Respostas de serviço

SendEvents() retorna um código de resposta HTTP do serviço. Um RequestFailedException é gerado como uma resposta de serviço para solicitações malsucedidas. A exceção contém informações sobre qual código de resposta foi retornado do serviço.

Desserializando dados de evento

  • Se os dados do evento não forem JSON válidos, um JsonException será gerado ao chamar Parse ou ParseMany.
  • Se o esquema de evento não corresponder ao tipo que está sendo desserializado para (por exemplo, chamar CloudEvent.Parse em um evento EventGridSchema), um ArgumentException será gerado.
  • Se Parse for chamado em dados que contenham vários eventos, um ArgumentException será gerado. ParseMany deve ser usado aqui em vez disso.

Configuração do registro em log do console

Também é possível habilitar registro em log do console facilmente se quiser se aprofundar nas solicitações que está fazendo ao serviço.

Rastreamento distribuído

A biblioteca da Grade de Eventos dá suporte à distribuição de rastreamento pronto para uso. Para aderir às diretrizes da especificação CloudEvents sobre a distribuição de rastreamento, a biblioteca define traceparent e tracestate no ExtensionAttributes de um CloudEvent quando o rastreamento distribuído está habilitado. Para saber mais sobre como habilitar o rastreamento distribuído em seu aplicativo, confira a documentação de rastreamento distribuído do SDK do Azure.

Grade de Eventos no Kubernetes

Essa biblioteca foi testada e validada no Kubernetes usando o Azure Arc.

Próximas etapas

Veja mais https://github.com/Azure/azure-sdk-for-net/blob/Azure.Messaging.EventGrid_4.20.0/sdk/eventgrid/Azure.Messaging.EventGrid/samples aqui para usos comuns da biblioteca de clientes da Grade de Eventos: Exemplos de Grade de Eventos.

Contribuição

Este projeto aceita contribuições e sugestões. A maioria das contribuições exige que você concorde com um CLA (Contrato de Licença do Colaborador) declarando que você tem o direito de nos conceder, e de fato concede, os direitos de usar sua contribuição. Para obter detalhes, visite Contratos de Licença do Colaborador.

Quando você envia uma solicitação de pull, um bot do CLA determina automaticamente se você precisa fornecer um CLA e preencher a PR corretamente (por exemplo, rótulo, comentário). Basta seguir as instruções fornecidas pelo bot. Você só precisará fazer isso uma vez em todos os repositórios que usam nosso CLA.

Este projeto adotou o Código de Conduta de Software Livre da Microsoft. Para obter mais informações, confira as Perguntas frequentes sobre o Código de Conduta ou contate opencode@microsoft.com para enviar outras perguntas ou comentários.

Impressões