Enviar mensagens e receber mensagens de filas de Azure Service Bus (Java)

Neste início rápido, vai criar uma aplicação Java para enviar mensagens e receber mensagens de uma fila de Azure Service Bus.

Nota

Este guia de introdução fornece instruções passo a passo para um cenário simples de enviar mensagens para uma fila do Service Bus e recebê-las. Pode encontrar exemplos java pré-criados para Azure Service Bus no repositório do SDK do Azure para Java no GitHub.

Dica

Se estiver a trabalhar com Azure Service Bus recursos numa aplicação Spring, recomendamos que considere o Spring Cloud Azure como uma alternativa. O Spring Cloud Azure é um projeto open source que proporciona uma integração totalmente integrada do Spring com os serviços do Azure. Para saber mais sobre o Spring Cloud Azure e ver um exemplo com o Service Bus, veja Spring Cloud Stream com Azure Service Bus.

Pré-requisitos

Criar um espaço de nomes no portal do Azure

Para começar a utilizar as entidades de mensagens do Service Bus no Azure, tem de, primeiro, criar um espaço de nomes que seja exclusivo em todo o Azure. Um espaço de nomes fornece um contentor de âmbito para os recursos do Service Bus na sua aplicação.

Para criar um espaço de nomes:

  1. Inicie sessão no portal do Azure.

  2. No painel de navegação esquerdo do portal, selecione Todos os serviços, selecione Integração na lista de categorias, paire o rato sobre o Service Bus e, em seguida, selecione Criar no mosaico Service Bus.

    Imagem a mostrar a seleção de Criar um recurso, Integração e, em seguida, Service Bus no menu.

  3. Na etiqueta Noções básicas da página Criar espaço de nomes , siga estes passos:

    1. Para Subscrição, selecione uma subscrição do Azure para criar o espaço de nomes.

    2. Para Grupo de recursos, selecione um grupo de recursos existente no qual o espaço de nomes irá viver ou crie um novo.

    3. Introduza um nome para o espaço de nomes. O nome do espaço de nomes deve cumprir as seguintes convenções de nomenclatura:

      • O nome tem de ser exclusivo em todo o Azure. O sistema verifica imediatamente a disponibilidade do nome.
      • O comprimento do nome é, pelo menos, 6 e, no máximo, 50 carateres.
      • O nome só pode conter letras, números, hífenes "-".
      • O nome tem de começar com uma letra e terminar com uma letra ou número.
      • O nome não termina com "-sb" ou "-mgmt".
    4. Em Localização, selecione a região na qual o espaço de nomes deve ser alojado.

    5. Para Escalão de preço, selecione o escalão de preço (Básico, Standard ou Premium) para o espaço de nomes. Para este início rápido, selecione Standard.

      Importante

      Se quiser utilizar tópicos e subscrições, escolha Standard ou Premium. Os tópicos/subscrições não são suportados no escalão de preço Básico.

      Se tiver selecionado o escalão de preço Premium , especifique o número de unidades de mensagens. O escalão premium fornece isolamento de recursos ao nível da CPU e da memória para que cada carga de trabalho seja executada isoladamente. Este contentor de recursos é designado por unidade de mensagens. Um espaço de nomes premium tem, pelo menos, uma unidade de mensagens. Pode selecionar 1, 2, 4, 8 ou 16 unidades de mensagens para cada espaço de nomes Premium do Service Bus. Para obter mais informações, consulte Mensagens Premium do Service Bus.

    6. Selecione Rever + criar na parte inferior da página.

      Imagem a mostrar a página Criar um espaço de nomes

    7. Na página Rever + criar , reveja as definições e selecione Criar.

  4. Assim que a implementação do recurso for bem-sucedida, selecione Ir para recurso na página de implementação.

    Imagem a mostrar a página implementação com êxito com a ligação Ir para recurso.

  5. Verá a home page do espaço de nomes do service bus.

    Imagem a mostrar a home page do espaço de nomes do Service Bus criado.

Criar uma fila no portal do Azure

  1. Na página Espaço de Nomes do Service Bus , selecione Filas no menu de navegação esquerdo.

  2. Na página Filas , selecione + Fila na barra de ferramentas.

  3. Introduza um nome para a fila e deixe os outros valores com as respetivas predefinições.

  4. Agora, selecione Criar.

    Imagem a mostrar a criação de uma fila no portal

Autenticar a aplicação no Azure

Este guia de introdução mostra-lhe duas formas de ligar a Azure Service Bus: sem palavra-passe e cadeia de ligação.

A primeira opção mostra-lhe como utilizar o principal de segurança no Azure Active Directory e o controlo de acesso baseado em funções (RBAC) para ligar a um espaço de nomes do Service Bus. Não precisa de se preocupar em ter uma cadeia de ligação codificada no seu código ou num ficheiro de configuração ou num armazenamento seguro, como o Azure Key Vault.

A segunda opção mostra-lhe como utilizar uma cadeia de ligação para ligar a um espaço de nomes do Service Bus. Se não estiver familiarizado com o Azure, poderá achar a opção de cadeia de ligação mais fácil de seguir. Recomendamos que utilize a opção sem palavra-passe em aplicações e ambientes de produção do mundo real. Para obter mais informações, veja Autenticação e autorização. Também pode ler mais sobre a autenticação sem palavra-passe na página de descrição geral.

Atribuir funções ao utilizador Azure AD

Ao desenvolver localmente, certifique-se de que a conta de utilizador que se liga ao Azure Service Bus tem as permissões corretas. Precisará da função de Proprietário de Dados Azure Service Bus para enviar e receber mensagens. Para atribuir esta função a si próprio, precisará da função Administrador de Acesso de Utilizador ou de outra função que inclua a ação Microsoft.Authorization/roleAssignments/write . Pode atribuir funções RBAC do Azure a um utilizador com o portal do Azure, a CLI do Azure ou Azure PowerShell. Saiba mais sobre os âmbitos disponíveis para atribuições de funções na página de descrição geral do âmbito .

O exemplo seguinte atribui a Azure Service Bus Data Owner função à sua conta de utilizador, que fornece acesso total a recursos Azure Service Bus. Num cenário real, siga o Princípio do Privilégio Mínimo para conceder aos utilizadores apenas as permissões mínimas necessárias para um ambiente de produção mais seguro.

Funções incorporadas do Azure para Azure Service Bus

Para Azure Service Bus, a gestão de espaços de nomes e todos os recursos relacionados através do portal do Azure e da API de gestão de recursos do Azure já está protegida com o modelo RBAC do Azure. O Azure fornece as funções incorporadas do Azure abaixo para autorizar o acesso a um espaço de nomes do Service Bus:

  • Azure Service Bus Proprietário de Dados: permite o acesso de dados ao espaço de nomes do Service Bus e às respetivas entidades (filas, tópicos, subscrições e filtros). Um membro desta função pode enviar e receber mensagens de filas ou tópicos/subscrições.
  • Azure Service Bus Remetente de Dados: utilize esta função para dar acesso ao espaço de nomes do Service Bus e às respetivas entidades.
  • Azure Service Bus Recetor de Dados: utilize esta função para dar acesso de receção ao espaço de nomes do Service Bus e às respetivas entidades.

Se quiser criar uma função personalizada, veja Direitos necessários para operações do Service Bus.

Adicionar Azure AD utilizador à função de Proprietário do Azure Service Bus

Adicione o Azure AD nome de utilizador à função de Proprietário de Dados do Azure Service Bus ao nível do espaço de nomes do Service Bus. Permitirá que uma aplicação em execução no contexto da sua conta de utilizador envie mensagens para uma fila ou tópico e receba mensagens de uma fila ou subscrição de um tópico.

Importante

Na maioria dos casos, a atribuição de funções demorará um ou dois minutos a propagar no Azure. Em casos raros, pode demorar até oito minutos. Se receber erros de autenticação quando executar o código pela primeira vez, aguarde alguns momentos e tente novamente.

  1. Se não tiver a página Espaço de Nomes do Service Bus aberta no portal do Azure, localize o espaço de nomes do Service Bus com a barra de pesquisa principal ou a navegação à esquerda.

  2. Na página de descrição geral, selecione Controlo de acesso (IAM) no menu esquerdo.

  3. Na página Controlo de acesso (IAM), selecione o separador Atribuições de funções .

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

    Uma captura de ecrã a mostrar como atribuir uma função.

  5. Utilize a caixa de pesquisa para filtrar os resultados para a função pretendida. Neste exemplo, procure Azure Service Bus Data Owner e selecione o resultado correspondente. Em seguida, selecione Seguinte.

  6. Em Atribuir acesso a, selecione Utilizador, grupo ou principal de serviço e, em seguida, selecione + Selecionar membros.

  7. Na caixa de diálogo, procure o seu nome de utilizador Azure AD (normalmente o seu endereço de e-mail user@domain) e, em seguida, selecione Selecionar na parte inferior da caixa de diálogo.

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

Enviar mensagens para uma fila

Nesta secção, vai criar um projeto de consola Java e adicionar código para enviar mensagens para a fila que criou anteriormente.

Criar um projeto de consola Java

Crie um projeto Java com o Eclipse ou uma ferramenta à sua escolha.

Configurar a aplicação para utilizar o Service Bus

Adicione referências ao Azure Core e Azure Service Bus bibliotecas.

Se estiver a utilizar o Eclipse e tiver criado uma aplicação de consola Java, converta o seu projeto Java num Maven: clique com o botão direito do rato no projeto na janela Explorador de Pacotes , selecione Configurar ->Converter para o projeto Maven. Em seguida, adicione dependências a estas duas bibliotecas, conforme mostrado no exemplo seguinte.

Atualize o pom.xml ficheiro para adicionar dependências ao Azure Service Bus e aos pacotes de Identidade do Azure.

    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-messaging-servicebus</artifactId>
            <version>7.13.3</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity</artifactId>
            <version>1.8.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

Adicionar código para enviar mensagens para a fila

  1. Adicione as seguintes import instruções no tópico do ficheiro Java.

    import com.azure.messaging.servicebus.*;
    import com.azure.identity.*;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    import java.util.Arrays;
    import java.util.List;
    
  2. Na classe , defina variáveis para conter a cadeia de ligação e o nome da fila.

    static String queueName = "<QUEUE NAME>";
    

    Importante

    Substitua <QUEUE NAME> pelo nome da fila.

  3. Adicione um método com o nome sendMessage na classe para enviar uma mensagem para a fila.

    Importante

    Substitua NAMESPACENAME pelo nome do espaço de nomes do Service Bus.

    static void sendMessage()
    {
        // create a token using the default Azure credential
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        ServiceBusSenderClient senderClient = new ServiceBusClientBuilder()
                .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
                .credential(credential)
                .sender()
                .queueName(queueName)
                .buildClient();
    
        // send one message to the queue
        senderClient.sendMessage(new ServiceBusMessage("Hello, World!"));
        System.out.println("Sent a single message to the queue: " + queueName);
    }
    
    
  4. Adicione um método com o nome createMessages na classe para criar uma lista de mensagens. Normalmente, recebe estas mensagens de diferentes partes da sua aplicação. Aqui, criamos uma lista de mensagens de exemplo.

    static List<ServiceBusMessage> createMessages()
    {
        // create a list of messages and return it to the caller
        ServiceBusMessage[] messages = {
                new ServiceBusMessage("First message"),
                new ServiceBusMessage("Second message"),
                new ServiceBusMessage("Third message")
        };
        return Arrays.asList(messages);
    }
    
  5. Adicione um método com o nome sendMessageBatch método para enviar mensagens para a fila que criou. Este método cria um ServiceBusSenderClient para a fila, invoca o createMessages método para obter a lista de mensagens, prepara um ou mais lotes e envia os lotes para a fila.

    Importante

    Substitua NAMESPACENAME pelo nome do espaço de nomes do Service Bus.

    static void sendMessageBatch()
    {
        // create a token using the default Azure credential
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        ServiceBusSenderClient senderClient = new ServiceBusClientBuilder()
                .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
                .credential(credential)
                .sender()
                .queueName(queueName)
                .buildClient();
    
        // Creates an ServiceBusMessageBatch where the ServiceBus.
        ServiceBusMessageBatch messageBatch = senderClient.createMessageBatch();
    
        // create a list of messages
        List<ServiceBusMessage> listOfMessages = createMessages();
    
        // We try to add as many messages as a batch can fit based on the maximum size and send to Service Bus when
        // the batch can hold no more messages. Create a new batch for next set of messages and repeat until all
        // messages are sent.
        for (ServiceBusMessage message : listOfMessages) {
            if (messageBatch.tryAddMessage(message)) {
                continue;
            }
    
            // The batch is full, so we create a new batch and send the batch.
            senderClient.sendMessages(messageBatch);
            System.out.println("Sent a batch of messages to the queue: " + queueName);
    
            // create a new batch
            messageBatch = senderClient.createMessageBatch();
    
            // Add that message that we couldn't before.
            if (!messageBatch.tryAddMessage(message)) {
                System.err.printf("Message is too large for an empty batch. Skipping. Max size: %s.", messageBatch.getMaxSizeInBytes());
            }
        }
    
        if (messageBatch.getCount() > 0) {
            senderClient.sendMessages(messageBatch);
            System.out.println("Sent a batch of messages to the queue: " + queueName);
        }
    
        //close the client
        senderClient.close();
    }
    

Receber mensagens de uma fila

Nesta secção, vai adicionar código para obter mensagens da fila.

  1. Adicione um método com o nome receiveMessages para receber mensagens da fila. Este método cria um ServiceBusProcessorClient para a fila ao especificar um processador para processar mensagens e outro para processar erros. Em seguida, inicia o processador, aguarda alguns segundos, imprime as mensagens recebidas e, em seguida, para e fecha o processador.

    Importante

    • Substitua NAMESPACENAME pelo nome do espaço de nomes do Service Bus.
    • Substitua QueueTest no QueueTest::processMessage código pelo nome da sua classe.
    // handles received messages
    static void receiveMessages() throws InterruptedException
    {
        CountDownLatch countdownLatch = new CountDownLatch(1);
    
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder()
                .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
                .credential(credential)
                .processor()
                .queueName(queueName)
                .processMessage(QueueTest::processMessage)
                .processError(context -> processError(context, countdownLatch))
                .buildProcessorClient();
    
        System.out.println("Starting the processor");
        processorClient.start();
    
        TimeUnit.SECONDS.sleep(10);
        System.out.println("Stopping and closing the processor");
        processorClient.close();
    }
    
  2. Adicione o processMessage método para processar uma mensagem recebida da subscrição do Service Bus.

    private static void processMessage(ServiceBusReceivedMessageContext context) {
        ServiceBusReceivedMessage message = context.getMessage();
        System.out.printf("Processing message. Session: %s, Sequence #: %s. Contents: %s%n", message.getMessageId(),
            message.getSequenceNumber(), message.getBody());
    }
    
  3. Adicione o processError método para processar mensagens de erro.

    private static void processError(ServiceBusErrorContext context, CountDownLatch countdownLatch) {
        System.out.printf("Error when receiving messages from namespace: '%s'. Entity: '%s'%n",
            context.getFullyQualifiedNamespace(), context.getEntityPath());
    
        if (!(context.getException() instanceof ServiceBusException)) {
            System.out.printf("Non-ServiceBusException occurred: %s%n", context.getException());
            return;
        }
    
        ServiceBusException exception = (ServiceBusException) context.getException();
        ServiceBusFailureReason reason = exception.getReason();
    
        if (reason == ServiceBusFailureReason.MESSAGING_ENTITY_DISABLED
            || reason == ServiceBusFailureReason.MESSAGING_ENTITY_NOT_FOUND
            || reason == ServiceBusFailureReason.UNAUTHORIZED) {
            System.out.printf("An unrecoverable error occurred. Stopping processing with reason %s: %s%n",
                reason, exception.getMessage());
    
            countdownLatch.countDown();
        } else if (reason == ServiceBusFailureReason.MESSAGE_LOCK_LOST) {
            System.out.printf("Message lock lost for message: %s%n", context.getException());
        } else if (reason == ServiceBusFailureReason.SERVICE_BUSY) {
            try {
                // Choosing an arbitrary amount of time to wait until trying again.
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.err.println("Unable to sleep for period of time");
            }
        } else {
            System.out.printf("Error source %s, reason %s, message: %s%n", context.getErrorSource(),
                reason, context.getException());
        }
    }
    
  4. Atualize o main método para invocar sendMessage, sendMessageBatche receiveMessages métodos e para lançar InterruptedException.

    public static void main(String[] args) throws InterruptedException {
        sendMessage();
        sendMessageBatch();
        receiveMessages();
    }
    

Executar a aplicação

  1. Se estiver a utilizar o Eclipse, clique com o botão direito do rato no projeto, selecione Exportar, expanda Java, selecione Ficheiro JAR executável e siga os passos para criar um ficheiro JAR executável.

  2. Se tiver sessão iniciada no computador com uma conta de utilizador diferente da conta de utilizador adicionada à função de Proprietário de Dados Azure Service Bus, siga estes passos. Caso contrário, ignore este passo e avance para executar o ficheiro Jar no passo seguinte.

    1. Instale a CLI do Azure no seu computador.

    2. Execute o seguinte comando da CLI para iniciar sessão no Azure. Utilize a mesma conta de utilizador que adicionou à função proprietário de dados Azure Service Bus.

      az login
      
  3. Execute o ficheiro Jar com o seguinte comando.

    java -jar <JAR FILE NAME>
    
  4. Verá o seguinte resultado na janela da consola.

    Sent a single message to the queue: myqueue
    Sent a batch of messages to the queue: myqueue
    Starting the processor
    Processing message. Session: 88d961dd801f449e9c3e0f8a5393a527, Sequence #: 1. Contents: Hello, World!
    Processing message. Session: e90c8d9039ce403bbe1d0ec7038033a0, Sequence #: 2. Contents: First message
    Processing message. Session: 311a216a560c47d184f9831984e6ac1d, Sequence #: 3. Contents: Second message
    Processing message. Session: f9a871be07414baf9505f2c3d466c4ab, Sequence #: 4. Contents: Third message
    Stopping and closing the processor
    

Na página Descrição geral do espaço de nomes do Service Bus na portal do Azure, pode ver a contagem de mensagens a receber e a enviar. Poderá ter de aguardar um minuto e, em seguida, atualizar a página para ver os valores mais recentes.

Contagem de mensagens recebidas e enviadas

Selecione a fila nesta página Descrição Geral para navegar para a página Fila do Service Bus . Também verá a contagem de mensagens recebidas e enviadas nesta página. Também verá outras informações, como o tamanho atual da fila, o tamanho máximo, a contagem de mensagens ativas, etc.

Detalhes da fila

Passos Seguintes

Veja a seguinte documentação e exemplos: