Envío de mensajes a un tema de Azure Service Bus y recepción de mensajes de las suscripciones a ese tema (Java)

En este inicio rápido, puede escribir código de Java con el paquete azure-messaging-servicebus para enviar mensajes a un tema de Azure Service Bus y recibir mensajes provenientes de las suscripciones a ese tema.

Nota

En este inicio rápido se proporcionan instrucciones detalladas para un escenario sencillo de envío de un lote de mensajes a un tema de Service Bus y recepción de esos mensajes desde una suscripción del tema. Puede encontrar más ejemplos pregenerados de Java para Azure Service Bus en el repositorio del SDK de Azure para Java en GitHub.

Sugerencia

Si trabaja con recursos de Azure Service Bus en una aplicación de Spring, se recomienda considerar el uso de Spring Cloud Azure como alternativa. Spring Cloud Azure es un proyecto de código abierto que proporciona una integración perfecta de Spring con los servicios de Azure. Para más información sobre Spring Cloud Azure y para ver un ejemplo con Service Bus, consulte Spring Cloud Stream con Azure Service Bus.

Requisitos previos

Creación de un espacio de nombres en Azure Portal

Para empezar a usar entidades de mensajería de Service Bus en Azure, primero hay que crear un espacio de nombres con un nombre que sea único en Azure. Un espacio de nombres proporciona un contenedor de ámbito para los recursos de Service Bus (colas, temas, etc.) que están dentro de la aplicación.

Para crear un espacio de nombres:

  1. Inicie sesión en Azure Portal.

  2. Vaya a la página Todos los servicios.

  3. En la barra de navegación izquierda, seleccione Integration en la lista de categorías, mantenga el mouse sobre Service Bus, y a continuación, seleccione el botón + en el mosaico de Service Bus.

    Imagen que muestra la selección de Crear un recurso, Integración y, posteriormente, Service Bus en el menú.

  4. En la pestaña Datos básicos de la página Crear espacio de nombres, siga estos pasos:

    1. En Suscripción, elija la suscripción de Azure en la que se va a crear el espacio de nombres.

    2. En Grupo de recursos, elija un grupo de recursos existente en el que residirá el espacio de nombres o cree uno.

    3. Escriba nombre para el espacio de nombres. El nombre del espacio de nombres debe cumplir las siguientes convenciones de nomenclatura:

      • El nombre debe ser único en Azure. El sistema realiza la comprobación automáticamente para ver si el nombre está disponible.
      • La longitud del nombre es de 6 caracteres como mínimo y 50 como máximo.
      • El nombre solo puede contener letras, números, guiones "-".
      • El nombre debe comenzar con una letra y terminar con una letra o un número.
      • El nombre no termina con "-sb" o "-mgmt".
    4. En Ubicación, elija la región donde se debe hospedar el espacio de nombres.

    5. En Plan de tarifa, seleccione el plan de tarifa (Básico, Estándar o Prémium) del espacio de nombres. Para este inicio rápido, seleccione Estándar.

      Importante

      Si desea usar temas y suscripciones, elija Estándar o Premium. El plan de tarifas Básico no admite temas o suscripciones.

      Si ha seleccionado el plan de tarifa Prémium, especifique el número de unidades de mensajería. El plan Premium proporciona aislamiento de recursos en el nivel de CPU y memoria para que cada carga de trabajo se ejecute de forma aislada. Este contenedor de recursos se llama unidad de mensajería. A cada espacio de nombres prémium se le asigna al menos una unidad de mensajería. Puede seleccionar 1, 2, 4, 8 o 16 unidades de mensajería para cada espacio de nombres prémium de Service Bus. Para más información, consulte Mensajería prémium de Service Bus.

    6. En la parte inferior de la página, seleccione Revisar y crear.

      Imagen que muestra la página Crear un espacio de nombres

    7. En la página Revisar y crear, examine la configuración y seleccione Crear.

  5. Una vez que la implementación del recurso sea correcta, seleccione Ir al recurso en la página de implementación.

    Imagen que muestra la página implementación correcta con el vínculo Ir al recurso.

  6. Verá la página principal del espacio de nombres de Service Bus.

    Imagen que muestra la página principal del espacio de nombres de Service Bus creado.

Creación de un tema mediante Azure Portal

  1. En la página Espacio de nombres de Service Bus, seleccione Temas en el menú izquierdo.

  2. En la barra de herramientas, seleccione + Tema.

  3. Escriba un nombre para el tema. Deje las restantes opciones con sus valores predeterminados.

  4. Seleccione Crear.

    Imagen que muestra la página Crear un tema.

Creación de una suscripción al tema

  1. Seleccione el tema que creó en la sección anterior.

    Imagen que muestra la selección del tema de la lista de temas.

  2. En la página Tema de Service Bus, seleccione Suscripción en la barra de herramientas.

    Imagen que muestra el botón Agregar suscripción.

  3. En la página Crear suscripción, siga estos pasos:

    1. Escriba S1 como nombre de la suscripción.

    2. Escriba 3 en Max delivery count (Número máximo de entregas).

    3. Luego, seleccione Create (Crear) para guardar la suscripción.

      Imagen que muestra la página Crear suscripción.

Autenticación de la aplicación en Azure

En este inicio rápido, se muestran dos maneras de conectarse a Azure Service Bus: sin contraseña y con la cadena de conexión.

La primera opción muestra cómo usar la entidad de seguridad en Microsoft Entra ID y el control de acceso basado en rol (RBAC) para conectarse a un espacio de nombres de Service Bus. No es necesario preocuparse por tener una cadena de conexión codificada de forma rígida en el código, en un archivo de configuración o en un almacenamiento seguro, como Azure Key Vault.

La segunda opción muestra cómo usar una cadena de conexión para conectarse a un espacio de nombres de Service Bus. Si no está familiarizado con Azure, puede que le resulte más fácil la opción de la cadena de conexión. Se recomienda usar la opción sin contraseña en aplicaciones reales y entornos de producción. Para más información, consulte Autenticación y autorización. También puede obtener más información sobre la autenticación sin contraseña en la página de información general.

Asignación de roles al usuario de Microsoft Entra

Al desarrollar localmente, asegúrese de que la cuenta de usuario que se conecta a Azure Service Bus tenga los permisos correctos. Necesitará el rol propietario de datos Azure Service Bus para enviar y recibir mensajes. Para asignarse este rol, necesitará el rol Administrador de accesos de usuarios, u otro que incluya la acción Microsoft.Authorization/roleAssignments/write. Puede asignar roles RBAC de Azure a un usuario mediante Azure Portal, la CLI de Azure o Azure PowerShell. Puede obtener más información sobre los ámbitos disponibles para las asignaciones de roles en la página de información general del ámbito.

En el ejemplo siguiente se asigna el rol Azure Service Bus Data Owner a la cuenta de usuario, que proporciona un acceso completo a los recursos de Azure Service Bus. En un escenario real, siga el Principio de privilegios mínimos para conceder a los usuarios solo los permisos mínimos necesarios para un entorno de producción más seguro.

Roles integrados de Azure para Azure Service Bus

En el caso de Azure Service Bus, la administración de los espacios de nombres y de todos los recursos relacionados mediante Azure Portal y la API de administración de recursos de Azure, ya se ha protegido mediante el modelo de Azure RBAC. Azure proporciona los siguientes roles integrados de Azure para autorizar el acceso a un espacio de nombres de Service Bus:

Si desea crear un rol personalizado, consulte Derechos necesarios para las operaciones de Service Bus.

Incorporación de un usuario de Microsoft Entra al rol Propietario de Azure Service Bus

Asigne el rol Propietario de datos de Azure Service Bus al nombre de usuario de Microsoft Entra en el nivel de espacio de nombres de Service Bus. Permitirá que una aplicación que se ejecuta en el contexto de la cuenta de usuario envíe mensajes a una cola o tema y reciba mensajes de la suscripción de una cola o tema.

Importante

En la mayoría de los casos, la asignación de roles tardará un minuto o dos en propagarse en Azure. En ocasiones excepcionales, puede tardar hasta ocho minutos. Si recibe errores de autenticación al ejecutar por primera vez el código, espere unos instantes e inténtelo de nuevo.

  1. Si no tiene abierta la página Espacio de nombres de Service Bus en Azure-Portal, busque el espacio de nombres de Service Bus mediante la barra de búsqueda principal o el panel de navegación izquierdo.

  2. En la página de información general, seleccione Control de acceso (IAM) en el menú de la izquierda.

  3. En la página Control de acceso (IAM), seleccione la pestaña Asignación de roles.

  4. Seleccione + Agregar en el menú superior y, a continuación, Agregar asignación de roles en el menú desplegable resultante.

    Una captura de pantalla que muestra cómo asignar un rol.

  5. Puede usar el cuadro de búsqueda para filtrar los resultados por el rol deseado. En este ejemplo, busque Azure Service Bus Data Owner y seleccione el resultado coincidente. Después, haga clic en Siguiente.

  6. En la pestaña Asignar acceso a, seleccione Usuario, grupo o entidad de servicio y, a continuación, elija + Seleccionar miembros.

  7. En el cuadro de diálogo, busque el nombre de usuario de Microsoft Entra (normalmente su dirección de correo electrónico de user@domain) y, a continuación, elija Seleccionar en la parte inferior del cuadro de diálogo.

  8. Seleccione Revisar y asignar para ir a la página final y, a continuación, de nuevo Revisar y asignar para completar el proceso.

Envío de mensajes a un tema

En esta sección creará un proyecto de consola de Java y agregará código para enviar mensajes al tema que ha creado.

Creación de un proyecto de consola de Java

Cree un proyecto de Java mediante Eclipse o la herramienta que prefiera.

Configuración de la aplicación para usar Service Bus

Agregue referencias a las bibliotecas de Azure Core y Azure Service Bus.

Si usa Eclipse y ha creado una aplicación de consola de Java, convierta el proyecto de Java a Maven: haga clic con el botón derecho en el proyecto en la ventana del Explorador de paquetes, seleccione Configurar ->Convert to Maven project (Convertir en proyecto de Maven). Luego, agregue dependencias a estas dos bibliotecas, tal como se muestra en el ejemplo siguiente.

Actualice el archivo pom.xml para agregar dependencias a Azure Service Bus y paquetes de identidad de 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>

Incorporación de código para enviar mensajes al tema

  1. Agregue las siguientes instrucciones import al principio del archivo Java.

    import com.azure.messaging.servicebus.*;
    import com.azure.identity.*;
    
    import java.util.concurrent.TimeUnit;
    import java.util.Arrays;
    import java.util.List;
    
  2. En la clase, defina variables para contener la cadena de conexión (no necesaria para el escenario sin contraseña), el nombre del tema y el nombre de la suscripción.

    static String topicName = "<TOPIC NAME>";
    static String subName = "<SUBSCRIPTION NAME>";
    

    Importante

    Reemplace <TOPIC NAME> por el nombre del tema y <SUBSCRIPTION NAME> por el nombre de la suscripción del tema.

  3. Agregue un método denominado sendMessage a la clase para enviar un mensaje al tema.

    Importante

    Reemplace NAMESPACENAME por el nombre del espacio de nombres de 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()
                .topicName(topicName)
                .buildClient();
    
        // send one message to the topic
        senderClient.sendMessage(new ServiceBusMessage("Hello, World!"));
        System.out.println("Sent a single message to the topic: " + topicName);
    }
    
    
  4. Agregue un método denominado createMessages a la clase para crear una lista de mensajes. Normalmente, estos mensajes se obtienen de distintas partes de la aplicación. En este caso crearemos una lista de mensajes de ejemplo.

    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. Agregue un método denominado sendMessageBatch para enviar mensajes al tema que ha creado. Este método crea un ServiceBusSenderClient para el tema, invoca el método createMessages para obtener la lista de mensajes, prepara uno o varios lotes y envía los lotes al tema.

    Importante

    Reemplace NAMESPACENAME por el nombre del espacio de nombres de 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()
                .topicName(topicName)
                .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 topic: " + topicName);
    
            // 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 topic: " + topicName);
        }
    
        //close the client
        senderClient.close();
    }
    

Recepción de mensajes de una suscripción

En esta sección agregará código para recuperar mensajes de una suscripción al tema.

  1. Agregue un método denominado receiveMessages para recibir mensajes de la suscripción. Este método crea un ServiceBusProcessorClient para la suscripción al especificar un controlador para procesar los mensajes y otro, para los errores. A continuación, inicia el procesador, espera unos segundos, imprime los mensajes que se reciben, y detiene y cierra el procesador.

    Importante

    • Reemplace NAMESPACENAME por el nombre del espacio de nombres de Service Bus.
    • Reemplace ServiceBusTopicTest en ServiceBusTopicTest::processMessage en el código por el nombre de la clase.
    // handles received messages
    static void receiveMessages() throws InterruptedException
    {
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        // Create an instance of the processor through the ServiceBusClientBuilder
        ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder()
            .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
            .credential(credential)
            .processor()
            .topicName(topicName)
            .subscriptionName(subName)
            .processMessage(context -> processMessage(context))
            .processError(context -> processError(context))
            .buildProcessorClient();
    
        System.out.println("Starting the processor");
        processorClient.start();
    
        TimeUnit.SECONDS.sleep(10);
        System.out.println("Stopping and closing the processor");
        processorClient.close();
    }
    
  2. Agregue el método processMessage para procesar un mensaje recibido de la suscripción de 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. Agregue el método processError para controlar los mensajes de error.

    private static void processError(ServiceBusErrorContext context) {
        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());
        } 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. Actualice el método main para invocar los métodos sendMessage, sendMessageBatch y receiveMessages, y para iniciar InterruptedException.

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

Ejecutar la aplicación

Ejecute el programa para ver una salida similar en la siguiente salida:

  1. Si usa Eclipse, haga clic con el botón derecho en el proyecto, seleccione Exportar, expanda Java, seleccione Archivo JAR ejecutable y siga los pasos para crear un archivo JAR ejecutable.

  2. Si ha iniciado sesión en la máquina con una cuenta de usuario diferente de la cuenta de usuario agregada al rol de Propietario de datos de Azure Service Bus, siga estos pasos. De lo contrario, omita este paso y continúe para ejecutar el archivo Jar en el paso siguiente.

    1. Instale la CLI de Azure en la máquina.

    2. Ejecute el siguiente comando de CLI para iniciar sesión en Azure. Use la misma cuenta de usuario que agregó al rol de propietario de datos de Azure Service Bus.

      az login
      
  3. Ejecute el archivo Jar con el siguiente comando.

    java -jar <JAR FILE NAME>
    
  4. Verá el resultado siguiente en la ventana de la consola:

    Sent a single message to the topic: mytopic
    Sent a batch of messages to the topic: mytopic
    Starting the processor
    Processing message. Session: e0102f5fbaf646988a2f4b65f7d32385, Sequence #: 1. Contents: Hello, World!
    Processing message. Session: 3e991e232ca248f2bc332caa8034bed9, Sequence #: 2. Contents: First message
    Processing message. Session: 56d3a9ea7df446f8a2944ee72cca4ea0, Sequence #: 3. Contents: Second message
    Processing message. Session: 7bd3bd3e966a40ebbc9b29b082da14bb, Sequence #: 4. Contents: Third message
    

En la página Información general del espacio de nombres de Service Bus en Azure Portal, verá el recuento de mensajes entrantes y salientes. Espere alrededor de un minuto y actualice la página para ver los valores más recientes.

Recuento de mensajes entrantes y salientes

Cambie a la pestaña Temas en el panel de la parte inferior y seleccione el tema para ver la página Tema de Service Bus de su tema. En esta página debería ver cuatro mensajes entrantes y cuatro salientes en el gráfico Mensajes.

Mensajes entrantes y salientes

Si marca la llamada receiveMessages en el método main y vuelve a ejecutar la aplicación, en la página Tema de Service Bus verá 8 mensajes entrantes (4 nuevos), pero cuatro mensajes salientes.

Página del tema actualizado

En esta página, si selecciona una suscripción, irá a la página Service Bus Subscription (Suscripción de Service Bus). En esta página puede ver el recuento de mensajes activos, el de mensajes con problemas de entrega y mucho más. En este ejemplo, hay cuatro mensajes activos que el receptor aún no ha recibido.

Recuento de mensajes activos

Pasos siguientes

Consulte la documentación y los ejemplos siguientes: