Usar o Java para enviar eventos ou receber eventos dos Hubs de Eventos do Azure

Este início rápido mostra como enviar e receber eventos de um hub de eventos usando o pacote Java azure-messaging-eventhubs.

Dica

Se você estiver trabalhando com recursos dos Hubs de Eventos do Azure em um aplicativo Spring, recomendamos considerar o Spring Cloud Azure como uma alternativa. O Spring Cloud Azure é um projeto de software livre que fornece integração perfeita do Spring com os serviços do Azure. Para saber mais sobre o Spring Cloud Azure e ver um exemplo usando Hubs de Eventos, confira Spring Cloud Stream com os Hubs de Eventos do Azure.

Pré-requisitos

Se você estiver conhecendo agora os Hubs de Eventos do Azure, confira Visão geral dos Hubs de Eventos antes de prosseguir com este início rápido.

Para concluir este início rápido, você precisará dos seguintes pré-requisitos:

  • Assinatura do Microsoft Azure. Para usar os serviços do Azure, incluindo os Hubs de Eventos do Azure, você precisa ter uma assinatura. Caso não tenha uma conta existente do Azure, inscreva-se em uma avaliação gratuita ou use os benefícios do assinante do MSDN quando criar uma conta.
  • Um ambiente de desenvolvimento Java. Este guia de início rápido usa Eclipse. É necessário um JDK (Java Development Kit) com a versão 8 ou superior.
  • Criar um namespace de Hubs de Eventos e um hub de eventos. A primeira etapa é usar o portal do Azure para criar um namespace do tipo Hubs de eventos e obter as credenciais de gerenciamento das quais que seu aplicativo precisa para se comunicar com o hub de eventos. Para criar um namespace e um hub de eventos, siga o procedimento nesse artigo. Em seguida, obtenha a cadeia de conexão para o namespace dos Hubs de Eventos seguindo as instruções do artigo: Obter a cadeia de conexão. Você usa a cadeia de conexão posteriormente no início rápido.

Enviar eventos

Esta seção mostra como criar um aplicativo Java para enviar eventos para um hub de eventos.

Adicionar a referência à biblioteca de Hubs de Eventos do Azure

Primeiro, crie um novo projeto Maven para um aplicativo de console/shell no ambiente de desenvolvimento Java favorito. Atualize o arquivo pom.xml conforme mostrado a seguir. A biblioteca de clientes Java para os Hubs de Eventos está disponível no Repositório Central do Maven.

		<dependency>
		    <groupId>com.azure</groupId>
		    <artifactId>azure-messaging-eventhubs</artifactId>
		    <version>5.18.0</version>
		</dependency>
		<dependency>
		    <groupId>com.azure</groupId>
		    <artifactId>azure-identity</artifactId>
		    <version>1.11.2</version>
		    <scope>compile</scope>
		</dependency>

Observação

Atualize a versão para a última versão publicada no repositório do Maven.

Autenticar o aplicativo no Azure

Este guia de início rápido mostra duas maneiras de se conectar aos Hubs de Eventos do Azure: sem senha e cadeia de conexão. A primeira opção mostra como usar sua entidade de segurança no Microsoft Entra ID e no RBAC (controle de acesso baseado em função) para se conectar a um namespace dos Hubs de Eventos. Você não precisa se preocupar em ter cadeias de conexão embutidas no código, em um arquivo de configuração ou em um armazenamento seguro, como o Azure Key Vault. A segunda opção mostra como usar uma cadeia de conexão para se conectar a um namespace dos Hubs de Eventos. Se você é novo no Azure, talvez ache a opção de cadeia de conexão mais fácil de ser seguida. É recomendável usar a opção sem senha em aplicativos do mundo real e ambientes de produção. Para obter mais informações, confira Autenticação e autorização. Você também pode ler mais sobre a autenticação sem senha na página de visão geral.

Atribuir funções ao usuário do Microsoft Entra

No caso de desenvolvimento local, verifique se a conta de usuário que se conecta aos Hubs de Eventos do Azure tem as permissões corretas. Você precisará da função Proprietário de Dados dos Hubs de Eventos do Azure para enviar e receber mensagens. Para atribuir essa função a si mesmo, você precisará da função Administrador de acesso do usuário ou de outra função que inclua a ação Microsoft.Authorization/roleAssignments/write. É possível atribuir funções RBAC do Azure a um usuário usando o portal do Azure, a CLI do Azure ou o Azure PowerShell. Saiba mais sobre os escopos disponíveis para atribuições de função na página de visão geral do escopo.

O exemplo a seguir atribui a função Azure Event Hubs Data Owner à sua conta de usuário, que fornece acesso completo aos recursos dos Hubs de Eventos do Azure. Em um cenário real, siga o Princípio do Privilégio Mínimo para dar aos usuários apenas as permissões mínimas necessárias para um ambiente de produção mais seguro.

Funções interna do Azure par Hubs de Eventos do Azure

Para os Hubs de Eventos do Azure, o gerenciamento de namespaces e de todos os recursos relacionados por meio do portal do Azure e da API de gerenciamento de recursos do Azure já está protegido pelo modelo Azure RBAC. O Azure fornece as funções internas do Azure abaixo para autorizar o acesso a um namespace dos Hubs de Eventos:

Se você quiser criar uma função personalizada, confira Direitos exigidos para operações dos Hubs de Eventos.

Importante

Na maioria dos casos, levará um ou dois minutos para a atribuição de função se propagar no Azure. Em casos raros, poderá levar até oito minutos. Se você receber erros de autenticação ao executar o código pela primeira vez, aguarde alguns instantes e tente novamente.

  1. No portal do Azure, localize o namespace dos Hubs de Eventos usando a barra de pesquisa principal ou a navegação à esquerda.

  2. Na página de visão geral, selecione Controle de acesso (IAM) no menu à esquerda.

  3. Na página Controle de acesso (IAM), selecione a guia Atribuições de função.

  4. Selecione + Adicionar no menu superior e, em seguida, Adicionar atribuição de função no menu suspenso resultante.

    A screenshot showing how to assign a role.

  5. Use a caixa de pesquisa para filtrar os resultados para a função desejada. Neste exemplo, pesquise Azure Event Hubs Data Owner e selecione o resultado correspondente. Em seguida, escolha Avançar.

  6. Em Atribuir acesso a, selecione Usuário, grupo ou entidade de serviço e, em seguida, selecione + Selecionar membros.

  7. No diálogo, pesquise seu nome de usuário do Microsoft Entra (geralmente seu endereço de email user@domain) e escolha Selecionar na parte inferior do diálogo.

  8. Selecione Revisar + atribuir para ir para a página final e, em seguida, Revisar + atribuir novamente para concluir o processo.

Escrever código para enviar mensagens ao hub de eventos

Adicione uma classe chamada Sender e adicione o seguinte código à classe:

Importante

  • Atualize <NAMESPACE NAME> com o nome do namespace dos Hubs de Eventos.
  • Atualize <EVENT HUB NAME> com o nome do seu hub de eventos.
package ehubquickstart;

import com.azure.messaging.eventhubs.*;
import java.util.Arrays;
import java.util.List;

import com.azure.identity.*;

public class SenderAAD {

    // replace <NAMESPACE NAME> with the name of your Event Hubs namespace.
    // Example: private static final String namespaceName = "contosons.servicebus.windows.net";
    private static final String namespaceName = "<NAMESPACE NAME>.servicebus.windows.net";

    // Replace <EVENT HUB NAME> with the name of your event hub. 
    // Example: private static final String eventHubName = "ordersehub";
    private static final String eventHubName = "<EVENT HUB NAME>";

    public static void main(String[] args) {
        publishEvents();
    }
    /**
     * Code sample for publishing events.
     * @throws IllegalArgumentException if the EventData is bigger than the max batch size.
     */
    public static void publishEvents() {
        // create a token using the default Azure credential        
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .authorityHost(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD)
                .build();

        // create a producer client        
        EventHubProducerClient producer = new EventHubClientBuilder()        
            .fullyQualifiedNamespace(namespaceName)
            .eventHubName(eventHubName)
            .credential(credential)
            .buildProducerClient();

        // sample events in an array
        List<EventData> allEvents = Arrays.asList(new EventData("Foo"), new EventData("Bar"));

        // create a batch
        EventDataBatch eventDataBatch = producer.createBatch();

        for (EventData eventData : allEvents) {
            // try to add the event from the array to the batch
            if (!eventDataBatch.tryAdd(eventData)) {
                // if the batch is full, send it and then create a new batch
                producer.send(eventDataBatch);
                eventDataBatch = producer.createBatch();

                // Try to add that event that couldn't fit before.
                if (!eventDataBatch.tryAdd(eventData)) {
                    throw new IllegalArgumentException("Event is too large for an empty batch. Max size: "
                        + eventDataBatch.getMaxSizeInBytes());
                }
            }
        }
        // send the last batch of remaining events
        if (eventDataBatch.getCount() > 0) {
            producer.send(eventDataBatch);
        }
        producer.close();
    }   
}

Compile o programa e certifique-se de que não existem erros. Você executará esse programa depois de executar o programa receptor.

Receber eventos

O código neste tutorial se baseia no exemplo de EventProcessorClient no GitHub, que você pode examinar para ver todo o aplicativo funcional.

Siga estas recomendações ao usar Armazenamento de Blobs do Azure como um repositório de ponto de verificação:

  • Use um contêiner separado para cada grupo de consumidores. Você pode usar a mesma conta de armazenamento, mas usar um contêiner por cada grupo.
  • Não use o contêiner para mais nada e não use a conta de armazenamento para mais nada.
  • A conta de armazenamento deve estar na mesma região em que o aplicativo implantado está localizado. Se o aplicativo for local, tente escolher a região mais próxima possível.

Na página Conta de armazenamento do portal do Azure, na seção serviço Blob, verifique se as seguintes configurações estão desabilitadas.

  • Namespace hierárquico
  • Exclusão temporária de blobs
  • Controle de versão

Criar um Armazenamento do Azure e um contêiner de blob

Neste guia de início rápido, você usará o Armazenamento do Azure (especificamente, o Armazenamento de Blobs) como o repositório de pontos de verificação. A marcação de pontos de verificação é um processo pelo qual um processador de eventos marca ou confirma a posição do último evento processado com êxito em uma partição. Normalmente, a marcação de um ponto de verificação é feita na função que processa os eventos. Para saber mais sobre a marcação de pontos de verificação, confira Processador de eventos.

Siga estas etapas para criar uma conta de Armazenamento do Azure.

  1. Crie uma conta de Armazenamento do Azure
  2. Crie um contêiner de blob
  3. Autenticar no contêiner de blob

Ao desenvolver localmente, verifique se a conta de usuário que está acessando os dados de blob tem as permissões corretas. Você precisará do Colaborador de Dados do Blob de Armazenamento para ler e gravar os dados de blob. Para atribuir essa função a si mesmo, você precisará receber a atribuição da função Administrador de Acesso do Usuário ou de outra função que inclua a ação Microsoft.Authorization/roleAssignments/write. É possível atribuir funções RBAC do Azure a um usuário usando o portal do Azure, a CLI do Azure ou o Azure PowerShell. Você pode saber mais sobre os escopos disponíveis para atribuições de função na página de visão geral do escopo.

Nesse cenário, você atribuirá permissões à sua conta de usuário, no escopo da conta de armazenamento, para seguir o Princípio do Privilégio Mínimo. Essa prática fornece aos usuários apenas as permissões mínimas necessárias e cria ambientes de produção mais seguros.

O exemplo a seguir atribuirá a função de Colaborador de Dados do Blob de Armazenamento à sua conta de usuário, que fornece acesso de leitura e gravação aos dados de blob na sua conta de armazenamento.

Importante

Na maioria dos casos, levará um ou dois minutos para a atribuição de função se propagar no Azure, mas em casos raros pode levar até oito minutos. Se você receber erros de autenticação ao executar o código pela primeira vez, aguarde alguns instantes e tente novamente.

  1. No portal do Azure, localize sua conta de armazenamento usando a barra de pesquisa principal ou a navegação à esquerda.

  2. Na página de visão geral da conta de armazenamento, selecione Controle de acesso (IAM) no menu à esquerda.

  3. Na página Controle de acesso (IAM), selecione a guia Atribuições de função.

  4. Selecione + Adicionar no menu superior e, em seguida, Adicionar atribuição de função no menu suspenso resultante.

    A screenshot showing how to assign a storage account role.

  5. Use a caixa de pesquisa para filtrar os resultados para a função desejada. Para este exemplo, pesquise o Colaborador de Dados do Blob de Armazenamento e selecione o resultado correspondente e, em seguida, escolha Avançar.

  6. Em Atribuir acesso a, selecione Usuário, grupo ou entidade de serviço e, em seguida, selecione + Selecionar membros.

  7. No diálogo, pesquise seu nome de usuário do Microsoft Entra (geralmente seu endereço de email user@domain) e escolha Selecionar na parte inferior do diálogo.

  8. Selecione Revisar + atribuir para ir para a página final e, em seguida, Revisar + atribuir novamente para concluir o processo.

Adicionar bibliotecas dos Hubs de Eventos ao seu projeto Java

Adicione as dependências a seguir ao arquivo pom.xml.

	<dependencies>
		<dependency>
		    <groupId>com.azure</groupId>
		    <artifactId>azure-messaging-eventhubs</artifactId>
		    <version>5.15.0</version>
		</dependency>
		<dependency>
		    <groupId>com.azure</groupId>
		    <artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
		    <version>1.16.1</version>
		</dependency>
		<dependency>
		    <groupId>com.azure</groupId>
		    <artifactId>azure-identity</artifactId>
		    <version>1.8.0</version>
		    <scope>compile</scope>
		</dependency>	
	</dependencies>
  1. Adicione as instruções import a seguir à parte superior do arquivo Java.

    import com.azure.messaging.eventhubs.*;
    import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
    import com.azure.messaging.eventhubs.models.*;
    import com.azure.storage.blob.*;
    import java.util.function.Consumer;
    
    import com.azure.identity.*;
    
  2. Crie uma classe chamada Receiver e adicione as variáveis de cadeia de caracteres a seguir à classe. Substitua os espaços reservados pelos valores corretos.

    Importante

    Substitua os espaços reservados pelos valores corretos.

    • <NAMESPACE NAME> pelo nome do namespace dos Hubs de Eventos.
    • <EVENT HUB NAME> pelo nome do hub de eventos no namespace.
    private static final String namespaceName = "<NAMESPACE NAME>.servicebus.windows.net";
    private static final String eventHubName = "<EVENT HUB NAME>";
    
  3. Adicione o método main a seguir à classe.

    Importante

    Substitua os espaços reservados pelos valores corretos.

    • <STORAGE ACCOUNT NAME> com o nome da sua conta de Armazenamento do Azure.
    • <CONTAINER NAME> com o nome do contêiner de blob na conta de armazenamento
    // create a token using the default Azure credential
    DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
            .authorityHost(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD)
            .build();
    
    // Create a blob container client that you use later to build an event processor client to receive and process events
    BlobContainerAsyncClient blobContainerAsyncClient = new BlobContainerClientBuilder()
            .credential(credential)
            .endpoint("https://<STORAGE ACCOUNT NAME>.blob.core.windows.net")
            .containerName("<CONTAINER NAME>")
            .buildAsyncClient();
    
    // Create an event processor client to receive and process events and errors.
    EventProcessorClient eventProcessorClient = new EventProcessorClientBuilder()
        .fullyQualifiedNamespace(namespaceName)
        .eventHubName(eventHubName)
        .consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME)
        .processEvent(PARTITION_PROCESSOR)
        .processError(ERROR_HANDLER)
        .checkpointStore(new BlobCheckpointStore(blobContainerAsyncClient))            
        .credential(credential)
        .buildEventProcessorClient();
    
    System.out.println("Starting event processor");
    eventProcessorClient.start();
    
    System.out.println("Press enter to stop.");
    System.in.read();
    
    System.out.println("Stopping event processor");
    eventProcessorClient.stop();
    System.out.println("Event processor stopped.");
    
    System.out.println("Exiting process");  
    
  1. Adicione os dois métodos auxiliares (PARTITION_PROCESSOR e ERROR_HANDLER) que processam eventos e erros para a classe Receiver.

    public static final Consumer<EventContext> PARTITION_PROCESSOR = eventContext -> {
        PartitionContext partitionContext = eventContext.getPartitionContext();
        EventData eventData = eventContext.getEventData();
    
        System.out.printf("Processing event from partition %s with sequence number %d with body: %s%n",
            partitionContext.getPartitionId(), eventData.getSequenceNumber(), eventData.getBodyAsString());
    
        // Every 10 events received, it will update the checkpoint stored in Azure Blob Storage.
        if (eventData.getSequenceNumber() % 10 == 0) {
            eventContext.updateCheckpoint();
        }
    };
    
    public static final Consumer<ErrorContext> ERROR_HANDLER = errorContext -> {
        System.out.printf("Error occurred in partition processor for partition %s, %s.%n",
            errorContext.getPartitionContext().getPartitionId(),
            errorContext.getThrowable());
    };
    
  2. Compile o programa e certifique-se de que não existem erros.

Executar os aplicativos

  1. Execute primeiro o aplicativo Destinatário.

  2. Em seguida, execute o aplicativo Remetente.

  3. Na janela do aplicativo Destinatário, confirme se os eventos publicados pelo aplicativo Remetente são exibidos.

    Starting event processor
    Press enter to stop.
    Processing event from partition 0 with sequence number 331 with body: Foo
    Processing event from partition 0 with sequence number 332 with body: Bar
    
  4. Pressione ENTER na janela do aplicativo receptor para interromper o aplicativo.

    Starting event processor
    Press enter to stop.
    Processing event from partition 0 with sequence number 331 with body: Foo
    Processing event from partition 0 with sequence number 332 with body: Bar
    
    Stopping event processor
    Event processor stopped.
    Exiting process
    

Próximas etapas

Confira as seguintes amostras no GitHub: