Probar aplicaciones de forma local con el emulador

Para desarrollar y probar tu aplicación de forma local, puedes usar el emulador de Pub/Sub, que ofrece una emulación local del servicio de producción de Pub/Sub. El emulador de Pub/Sub se ejecuta con la CLI de Google Cloud.

Para ejecutar la aplicación en el emulador, primero inicia el emulador y define las variables de entorno. Tu aplicación debe comunicarse con el emulador en lugar de con el servicio de producción de Pub/Sub. Los recursos creados y los mensajes publicados en el emulador se mantienen durante la duración de la sesión del emulador.

Antes de empezar

Completa los siguientes requisitos previos antes de usar el emulador de Pub/Sub:

Instalar el emulador

Instala el emulador desde una petición de comando:

gcloud components install pubsub-emulator
gcloud components update

Instalar el emulador como imagen de contenedor

Para instalar y ejecutar el emulador como contenedor, descarga e instala la imagen Docker de gcloud.

Iniciar el emulador

Inicia el emulador invocando pubsub start desde un símbolo del sistema. Antes de ejecutar el comando, sustituye PUBSUB_PROJECT_ID por unGoogle Cloud ID de proyecto válido. La cadena no tiene que representar un proyecto real de Google Cloud porque el emulador de Pub/Sub se ejecuta de forma local.

gcloud beta emulators pubsub start --project=PUBSUB_PROJECT_ID [options]

Consulta la gcloud beta emulators pubsub start para ver la lista completa de marcas.

Después de iniciar el emulador, verás un mensaje similar al siguiente:

...
[pubsub] This is the Pub/Sub fake.
[pubsub] Implementation may be incomplete or differ from the real system.
...
[pubsub] INFO: Server started, listening on 8085

Este mensaje indica que el servidor de Pub/Sub se ejecuta en el endpoint del emulador de tu máquina local en lugar del endpoint Google Cloud . Todas las operaciones se realizan de forma local, incluidas las siguientes:

  • Crear un tema o una suscripción
  • Publicación
  • Suscribiéndose

Configurar variables de entorno

Después de iniciar el emulador, debes definir las variables de entorno para que tu aplicación se conecte al emulador en lugar de a Pub/Sub. Define estas variables de entorno en el mismo equipo que usas para ejecutar tu aplicación.

Debes definir las variables de entorno cada vez que inicies el emulador. Las variables de entorno dependen de los números de puerto asignados dinámicamente, que podrían cambiar al reiniciar el emulador.

Definir las variables automáticamente

Si tu aplicación y el emulador se ejecutan en el mismo ordenador, puedes definir las variables de entorno automáticamente:

Linux o macOS

Ejecuta env-init mediante la sustitución de comandos:

$(gcloud beta emulators pubsub env-init)

Windows

Crea y ejecuta un archivo por lotes con la salida de env-init:

gcloud beta emulators pubsub env-init > set_vars.cmd && set_vars.cmd

Tu aplicación se conectará al emulador de Pub/Sub.

Definir las variables manualmente

Si tu aplicación y el emulador se ejecutan en máquinas diferentes, define las variables de entorno manualmente:

  1. Ejecuta el comando env-init:

     gcloud beta emulators pubsub env-init

  2. En la máquina que ejecuta tu aplicación, define la variable de entorno PUBSUB_EMULATOR_HOST y el valor según las indicaciones de la salida del comando env-init. Esta configuración conecta tu aplicación al emulador. También puedes definir la variable de entorno PUBSUB_PROJECT_ID para el proyecto que quieras usar en el emulador.

    Linux o macOS
    export PUBSUB_EMULATOR_HOST=[::1]:8432
    export PUBSUB_PROJECT_ID=my-project-id
    Windows
    set PUBSUB_EMULATOR_HOST=[::1]:8432
    set PUBSUB_PROJECT_ID=my-project-id

Tu aplicación se conectará al emulador de Pub/Sub.

Nota: Si usas el servidor de desarrollo local de Python App Engine Standard, debes pasar esta variable de entorno en la línea de comandos de la siguiente manera:

dev_appserver.py app.yaml --env_var PUBSUB_EMULATOR_HOST=${PUBSUB_EMULATOR_HOST}

dev_appserver.py está incluido en tu [PATH_TO_CLOUD_SDK]/google-cloud-sdk/bin/dev_appserver.py.

Usar el emulador

Para usar el emulador, debes tener una aplicación creada con las bibliotecas de cliente de Cloud. El emulador no admite los comandos Google Cloud console ni gcloud pubsub.

En el siguiente ejemplo se muestra cómo usar el emulador y una aplicación que usa la biblioteca de cliente de Cloud para Python para realizar varias operaciones. Algunos ejemplos de estas operaciones son cómo crear un tema, publicar mensajes y leer mensajes.

Sigue estos pasos en el equipo en el que hayas definido las variables de entorno del emulador:

  1. Obtén las muestras de Python de Pub/Sub de GitHub clonando el repositorio completo de Python.

  2. En el repositorio clonado, ve al directorio samples/snippets. Completa el resto de los pasos en este directorio.

  3. En el directorio samples/snippets, instala las dependencias que necesites para ejecutar el ejemplo:

    pip install -r requirements.txt
    
  4. Para crear un tema, sigue estos pasos:

     python publisher.py PUBSUB_PROJECT_ID create TOPIC_ID
    
  5. (Opcional) Si no tienes ningún endpoint push local para probar las suscripciones push en el emulador, sigue estos pasos para crear uno en http://[::1]:3000/messages.

    1. Instala JSON Server.
      npm install -g json-server
      
    2. Inicia el servidor JSON.
      json-server --port 3000 --watch db.json
      
      donde db.json contiene el siguiente código inicial:
      {
         "messages": []
      }
      
    3. Anota http://[::1]:3000/messages para PUSH_ENDPOINT en el siguiente paso.
  6. Crea una suscripción al tema:

    • Para crear una suscripción de extracción, sigue estos pasos:

      python subscriber.py PUBSUB_PROJECT_ID create TOPIC_ID SUBSCRIPTION_ID
      
    • Para crear una suscripción de inserción, sigue estos pasos:

      python subscriber.py PUBSUB_PROJECT_ID create-push TOPIC_ID SUBSCRIPTION_ID \
      PUSH_ENDPOINT
      
  7. Publica mensajes en el tema:

     python publisher.py PUBSUB_PROJECT_ID publish TOPIC_ID
    
  8. Lee los mensajes publicados en el tema:

    • Para recuperar mensajes de tu suscripción de extracción, sigue estos pasos:

      python subscriber.py PUBSUB_PROJECT_ID receive SUBSCRIPTION_ID
      
    • Observa los mensajes enviados a tu endpoint push local. Por ejemplo, los mensajes tienen el siguiente aspecto:

      {
        "messages": [
            {
                "subscription": "projects/PUBSUB_PROJECT_ID/subscriptions/SUBSCRIPTION_ID",
                "message": {
                    "data": "TWVzc2FnZSBudW1iZXIgMQ==",
                    "messageId": "10",
                    "attributes": {}
                },
                "id": 1
            },
            ...
        ]
      }
      

Acceder a variables de entorno

En todos los lenguajes, excepto Java y C#, si has definido PUBSUB_EMULATOR_HOST tal como se describe en Definir variables de entorno, las bibliotecas de cliente de Pub/Sub llaman automáticamente a la API que se ejecuta en la instancia local en lugar de a Pub/Sub.

Sin embargo, las bibliotecas de cliente de C# y Java requieren que modifiques el código para usar el emulador:

C#

Antes de probar este ejemplo, sigue las instrucciones de configuración de C# que se indican en la guía de inicio rápido de Pub/Sub con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API C# Pub/Sub.

Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.


using Google.Api.Gax;
using Google.Cloud.PubSub.V1;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class EmulatorSupportSample
{
    public async Task WithEmulatorAsync(string projectId, string topicId, string subscriptionId)
    {
        // Use EmulatorDetection.EmulatorOrProduction to create service clients that will
        // that will connect to the PubSub emulator if the PUBSUB_EMULATOR_HOST environment
        // variable is set, but will otherwise connect to the production environment.

        // Create the PublisherServiceApiClient using the PublisherServiceApiClientBuilder
        // and setting the EmulatorDection property.
        PublisherServiceApiClient publisherService = await new PublisherServiceApiClientBuilder
        {
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();

        // Use the client as you'd normally do, to create a topic in this example.
        TopicName topicName = new TopicName(projectId, topicId);
        publisherService.CreateTopic(topicName);

        // Create the SubscriberServiceApiClient using the SubscriberServiceApiClientBuilder
        // and setting the EmulatorDection property.
        SubscriberServiceApiClient subscriberService = await new SubscriberServiceApiClientBuilder
        {
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();

        // Use the client as you'd normally do, to create a subscription in this example.
        SubscriptionName subscriptionName = new SubscriptionName(projectId, subscriptionId);
        subscriberService.CreateSubscription(subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60);

        // Create the PublisherClient using PublisherClientBuilder to set the EmulatorDetection property.
        PublisherClient publisher = await new PublisherClientBuilder
        {
            TopicName = topicName,
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();
        // Use the client as you'd normally do, to send a message in this example.
        await publisher.PublishAsync("Hello, Pubsub");
        await publisher.ShutdownAsync(TimeSpan.FromSeconds(15));

        // Create the SubscriberClient using SubscriberClientBuild to set the EmulatorDetection property.
        SubscriberClient subscriber = await new SubscriberClientBuilder
        {
            SubscriptionName = subscriptionName,
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();
        List<PubsubMessage> receivedMessages = new List<PubsubMessage>();

        // Use the client as you'd normally do, to listen for messages in this example.
        await subscriber.StartAsync((msg, cancellationToken) =>
        {
            receivedMessages.Add(msg);
            Console.WriteLine($"Received message {msg.MessageId} published at {msg.PublishTime.ToDateTime()}");
            Console.WriteLine($"Text: '{msg.Data.ToStringUtf8()}'");
            // In this example we stop the subscriber when the message is received.
            // You may leave the subscriber running, and it will continue to received published messages
            // if any.
            // This is non-blocking, and the returned Task may be awaited.
            subscriber.StopAsync(TimeSpan.FromSeconds(15));
            // Return Reply.Ack to indicate this message has been handled.
            return Task.FromResult(SubscriberClient.Reply.Ack);
        });
    }
}

Java

Antes de probar este ejemplo, sigue las instrucciones de configuración de Java que se indican en la guía de inicio rápido de Pub/Sub con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Java Pub/Sub.

Para autenticarte en Pub/Sub, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación en un entorno de desarrollo local.


import com.google.api.core.ApiFuture;
import com.google.api.gax.core.CredentialsProvider;
import com.google.api.gax.core.NoCredentialsProvider;
import com.google.api.gax.grpc.GrpcTransportChannel;
import com.google.api.gax.rpc.FixedTransportChannelProvider;
import com.google.api.gax.rpc.TransportChannelProvider;
import com.google.cloud.pubsub.v1.Publisher;
import com.google.cloud.pubsub.v1.TopicAdminClient;
import com.google.cloud.pubsub.v1.TopicAdminSettings;
import com.google.protobuf.ByteString;
import com.google.pubsub.v1.PubsubMessage;
import com.google.pubsub.v1.Topic;
import com.google.pubsub.v1.TopicName;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

public class UsePubSubEmulatorExample {
  public static void main(String... args) throws Exception {
    String hostport = System.getenv("PUBSUB_EMULATOR_HOST");
    ManagedChannel channel = ManagedChannelBuilder.forTarget(hostport).usePlaintext().build();
    try {
      TransportChannelProvider channelProvider =
          FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
      CredentialsProvider credentialsProvider = NoCredentialsProvider.create();

      // Set the channel and credentials provider when creating a `TopicAdminClient`.
      // Can be done similarly for a `SubscriptionAdminClient`.
      TopicAdminClient topicAdminClient =
          TopicAdminClient.create(
              TopicAdminSettings.newBuilder()
                  .setTransportChannelProvider(channelProvider)
                  .setCredentialsProvider(credentialsProvider)
                  .build());

      TopicName topicName = TopicName.of("my-project-id", "my-topic-id");
      Topic topic = topicAdminClient.createTopic(topicName);
      System.out.println("Created topic: " + topic.getName());

      // Set the channel and credentials provider when creating a `Publisher`.
      // Can be done similarly for a `Subscriber`.
      Publisher publisher =
          Publisher.newBuilder(topicName)
              .setChannelProvider(channelProvider)
              .setCredentialsProvider(credentialsProvider)
              .build();

      String message = "Hello World!";
      ByteString data = ByteString.copyFromUtf8(message);
      PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();

      ApiFuture<String> messageIdFuture = publisher.publish(pubsubMessage);
      String messageId = messageIdFuture.get();
      System.out.println("Published message ID: " + messageId);
    } finally {
      channel.shutdown();
    }
  }
}

Detener el emulador

Para detener el emulador, pulsa Control + C.

Después de detener el emulador, ejecuta el siguiente comando para quitar la variable de entorno PUBSUB_EMULATOR_HOST de forma que tu aplicación se conecte a Pub/Sub:

Linux o macOS
unset PUBSUB_EMULATOR_HOST
Windows
set PUBSUB_EMULATOR_HOST=

Argumentos de línea de comandos del emulador

Para obtener información sobre los argumentos de línea de comandos del emulador de Pub/Sub, consulta gcloud beta emulators pubsub.

Funciones compatibles

El emulador admite las siguientes funciones de Pub/Sub:

  • Publicar mensajes
  • Recibir mensajes de suscripciones push y pull
  • Ordenar mensajes
  • Volver a reproducir mensajes
  • Reenviar mensajes a temas de mensajes fallidos
  • Políticas de reintentos en la entrega de mensajes
  • Compatibilidad con esquemas de Avro

Limitaciones conocidas

  • No se admiten las RPCs de UpdateTopic y UpdateSnapshot.
  • No se admiten las operaciones de gestión de identidades y accesos.
  • No se admite la conservación de mensajes configurable; todos los mensajes se conservan indefinidamente.
  • No se admite la caducidad de la suscripción. Las suscripciones no caducan.
  • No se admite el filtrado.
  • Compatibilidad con esquemas de búferes de protocolo.
  • Se pueden crear suscripciones de BigQuery, pero no se envían mensajes a BigQuery.
  • No se admite la búsqueda por marca de tiempo en suscripciones ordenadas.
  • Los temas y las suscripciones se pueden crear con transformaciones de un solo mensaje (SMTs), pero los mensajes no se transformarán.

Para registrar incidencias, envía una herramienta de seguimiento de incidencias pública.

Siguientes pasos