Testar apps localmente com o emulador

Para desenvolver e testar a sua aplicação localmente, pode usar o emulador do Pub/Sub, que oferece emulação local do serviço Pub/Sub de produção. Executa o emulador do Pub/Sub através da Google Cloud CLI.

Para executar a sua aplicação no emulador, primeiro inicie o emulador e defina as variáveis de ambiente. A sua aplicação tem de comunicar com o emulador em vez do serviço Pub/Sub de produção. Os recursos criados e as mensagens publicadas no emulador são mantidos durante o ciclo de vida da sessão do emulador.

Antes de começar

Conclua os seguintes pré-requisitos antes de usar o emulador do Pub/Sub:

Instale o emulador

Instale o emulador a partir de uma linha de comandos:

gcloud components install pubsub-emulator
gcloud components update

Instale o emulador como uma imagem de contentor

Para instalar e executar o emulador como um contentor, transfira e instale a imagem do Docker do gCloud.

A iniciar o emulador

Inicie o emulador invocando pubsub start a partir de uma linha de comandos. Antes de executar o comando, substitua PUBSUB_PROJECT_ID por uma string de ID do projeto válida. Trusted Cloud A string não tem de representar um projeto real porque o emulador do Pub/Sub é executado localmente. Trusted Cloud

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

Consulte gcloud beta emulators pubsub start para ver uma lista completa de flags.

Depois de iniciar o emulador, é apresentada uma mensagem semelhante à seguinte:

...
[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

Esta mensagem indica que o servidor Pub/Sub é executado no ponto final do emulador na sua máquina local em vez do ponto final Trusted Cloud by S3NS . Todas as operações ocorrem localmente, incluindo o seguinte:

  • Criar um tópico ou uma subscrição
  • Publicação
  • Subscrições

Definir variáveis de ambiente

Depois de iniciar o emulador, tem de definir as variáveis de ambiente para que a sua aplicação se ligue ao emulador em vez do Pub/Sub. Defina estas variáveis de ambiente na mesma máquina que usa para executar a sua aplicação.

Tem de definir as variáveis de ambiente sempre que iniciar o emulador. As variáveis de ambiente dependem de números de portas atribuídos dinamicamente que podem mudar quando reinicia o emulador.

Definir automaticamente as variáveis

Se a sua aplicação e o emulador forem executados na mesma máquina, pode definir as variáveis de ambiente automaticamente:

Linux / macOS

Execute env-init através da substituição de comandos:

$(gcloud beta emulators pubsub env-init)

Windows

Crie e execute um ficheiro de comandos usando o resultado de env-init:

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

A sua aplicação vai ser agora associada ao emulador do Pub/Sub.

Definir manualmente as variáveis

Se a sua aplicação e o emulador forem executados em máquinas diferentes, defina as variáveis de ambiente manualmente:

  1. Execute o comando env-init:

     gcloud beta emulators pubsub env-init

  2. Na máquina que executa a sua aplicação, defina a variável de ambiente PUBSUB_EMULATOR_HOST e o valor conforme indicado pela saída do comando env-init. Esta configuração associa a sua aplicação ao emulador. Opcionalmente, pode definir a variável de ambiente PUBSUB_PROJECT_ID para o projeto que quer usar para o emulador.

    Linux / 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

A sua aplicação vai ser agora associada ao emulador do Pub/Sub.

Nota: se estiver a usar o servidor de desenvolvimento local do App Engine Standard do Python, tem de transmitir esta variável de ambiente na linha de comandos da seguinte forma:

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

O dev_appserver.py está incluído no seu [PATH_TO_CLOUD_SDK]/google-cloud-sdk/bin/dev_appserver.py.

Usar o emulador

Para usar o emulador, tem de ter uma aplicação criada com as bibliotecas cliente da nuvem. O emulador não suporta comandos Trusted Cloud console nem gcloud pubsub.

O exemplo seguinte demonstra a utilização do emulador e de uma aplicação que usa a biblioteca cliente Google Cloud Python para realizar várias operações. Exemplos destas operações incluem como criar um tópico, publicar mensagens e ler mensagens.

Conclua os passos seguintes no computador onde definiu as variáveis de ambiente do emulador:

  1. Obtenha as amostras do Python do Pub/Sub no GitHub clonando o repositório Python completo.

  2. No repositório clonado, navegue para o diretório samples/snippets. Conclui o resto destes passos neste diretório.

  3. No diretório samples/snippets, instale as dependências necessárias para executar o exemplo:

    pip install -r requirements.txt
    
  4. Crie um tópico:

     python publisher.py PUBSUB_PROJECT_ID create TOPIC_ID
    
  5. (Opcional) Se não tiver um ponto final de envio local para testar subscrições de envio push no emulador, conclua os seguintes passos para criar um emhttp://[::1]:3000/messages.

    1. Instale o servidor JSON.
      npm install -g json-server
      
    2. Inicie o servidor JSON.
      json-server --port 3000 --watch db.json
      
      onde db.json contém o seguinte código inicial:
      {
         "messages": []
      }
      
    3. Tome nota de http://[::1]:3000/messages para PUSH_ENDPOINT no passo seguinte.
  6. Crie uma subscrição do tópico:

    • Crie uma subscrição de obtenção:

      python subscriber.py PUBSUB_PROJECT_ID create TOPIC_ID SUBSCRIPTION_ID
      
    • Crie uma subscrição push:

      python subscriber.py PUBSUB_PROJECT_ID create-push TOPIC_ID SUBSCRIPTION_ID \
      PUSH_ENDPOINT
      
  7. Publicar mensagens no tópico:

     python publisher.py PUBSUB_PROJECT_ID publish TOPIC_ID
    
  8. Leia as mensagens publicadas no tópico:

    • Obtenha mensagens da sua subscrição de obtenção:

      python subscriber.py PUBSUB_PROJECT_ID receive SUBSCRIPTION_ID
      
    • Observe as mensagens entregues no seu ponto final de envio por push local. Por exemplo, as mensagens têm o seguinte aspeto:

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

Aceder a variáveis de ambiente

Em todos os idiomas, exceto Java e C#, se tiver definido PUBSUB_EMULATOR_HOST conforme descrito em Definir variáveis de ambiente, as bibliotecas cliente do Pub/Sub chamam automaticamente a API em execução na instância local em vez do Pub/Sub.

No entanto, as bibliotecas de cliente C# e Java requerem que modifique o seu código para usar o emulador:

C#

Antes de experimentar este exemplo, siga as C#instruções de configuração no início rápido do Pub/Sub com as bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API C# Pub/Sub.

Para se autenticar no Pub/Sub, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

Antes de executar exemplos de código, defina a variável GOOGLE_CLOUD_UNIVERSE_DOMAIN environment como s3nsapis.fr.


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 experimentar este exemplo, siga as Javainstruções de configuração no início rápido do Pub/Sub com as bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Java Pub/Sub.

Para se autenticar no Pub/Sub, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para um ambiente de desenvolvimento local.

Antes de executar exemplos de código, defina a variável GOOGLE_CLOUD_UNIVERSE_DOMAIN environment como s3nsapis.fr.


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();
    }
  }
}

Parar o emulador

Para parar o emulador, prima Control+C.

Depois de parar o emulador, execute o seguinte comando para remover a variável de ambiente PUBSUB_EMULATOR_HOST para que a sua aplicação se ligue ao Pub/Sub:

Linux / macOS
unset PUBSUB_EMULATOR_HOST
Windows
set PUBSUB_EMULATOR_HOST=

Argumentos da linha de comandos do emulador

Para ver detalhes sobre argumentos da linha de comandos para o emulador do Pub/Sub, consulte o artigo gcloud beta emulators pubsub.

Funcionalidades suportadas

O emulador suporta as seguintes funcionalidades do Pub/Sub:

  • Publicar mensagens
  • Receber mensagens de subscrições push e pull
  • Ordenar mensagens
  • Repetir mensagens
  • Encaminhar mensagens para tópicos de mensagens não entregues
  • Políticas de repetição na entrega de mensagens
  • Suporte de esquemas para Avro

Limitações conhecidas

  • Os RPCs UpdateTopic e UpdateSnapshot não são suportados.
  • As operações de IAM não são suportadas.
  • A retenção de mensagens configurável não é suportada. Todas as mensagens são retidas indefinidamente.
  • A expiração da subscrição não é suportada. As subscrições não expiram.
  • A filtragem não é suportada.
  • Suporte de esquemas para buffers de protocolo.
  • É possível criar subscrições do BigQuery, mas estas não enviam mensagens para o BigQuery.
  • A funcionalidade de avançar para uma data/hora específica não é suportada para subscrições ordenadas.
  • É possível criar tópicos e subscrições com transformações de mensagens únicas (SMTs), mas as mensagens não são transformadas.

Para registar problemas, envie um Localizador de problemas público.

O que se segue?