Test delle applicazioni in locale con l'emulatore

Per sviluppare e testare l'applicazione a livello locale, puoi utilizzare l'emulatore Pub/Sub, che fornisce l'emulazione locale del servizio Pub/Sub di produzione. Devi eseguire Pub/Sub con Google Cloud CLI.

Per eseguire l'applicazione sull'emulatore, avvia prima l'emulatore e imposta le variabili di ambiente. L'applicazione deve comunicare con l'emulatore anziché con il servizio Pub/Sub di produzione. La le risorse create e i messaggi pubblicati nell'emulatore vengono mantenuti della sessione dell'emulatore.

Prima di iniziare

Completa i seguenti prerequisiti prima di utilizzare Pub/Sub emulator:

Installa l'emulatore

Installa l'emulatore da un prompt dei comandi:

gcloud components install pubsub-emulator
gcloud components update

Installa l'emulatore come immagine container

Per installare ed eseguire l'emulatore come container, scarica e installa l'immagine Docker gCloud.

Avvio dell'emulatore

Avvia l'emulatore richiamando pubsub start da un prompt dei comandi. Prima del giorno comando, sostituisci PUBSUB_PROJECT_ID con ID progetto Google Cloud. stringa. La stringa non deve necessariamente rappresentano un vero e proprio progetto Google Cloud perché L'emulatore Pub/Sub viene eseguito in locale.

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

Per un elenco completo dei flag, consulta gcloud beta emulators pubsub start.

Dopo aver avviato l'emulatore, viene visualizzato un messaggio simile al seguente:

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

Questo messaggio indica che il server Pub/Sub viene eseguito nell'endpoint dell'emulatore sul computer locale anziché nell'endpoint di Google Cloud. Tutte le operazioni avvengono localmente, tra cui:

  • Creazione di un argomento o di una sottoscrizione
  • In fase di pubblicazione
  • Sottoscrizione in corso

Imposta le variabili di ambiente

Dopo aver avviato l'emulatore, devi impostare le variabili di ambiente in modo che si connette all'emulatore anziché a Pub/Sub. Imposta queste variabili di ambiente sulla stessa macchina che utilizzi per eseguire l'applicazione.

Devi impostare le variabili di ambiente a ogni avvio dell'emulatore. La dipendono da numeri di porta assegnati dinamicamente che potrebbero cambia quando riavvii l'emulatore.

Impostazione automatica delle variabili

Se l'applicazione e l'emulatore vengono eseguiti sullo stesso computer, puoi impostare automaticamente le variabili di ambiente:

Linux / MacOS

Esegui env-init utilizzando la sostituzione dei comandi:

$(gcloud beta emulators pubsub env-init)

Windows

Crea ed esegui un file batch utilizzando l'output di env-init:

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

L'applicazione si connetterà all'emulatore Pub/Sub.

Impostazione manuale delle variabili

Se l'applicazione e l'emulatore vengono eseguiti su macchine diverse, imposta manualmente le variabili di ambiente:

  1. Esegui il comando env-init:

     gcloud beta emulators pubsub env-init

  2. Sulla macchina su cui viene eseguita l'applicazione, imposta la variabile di ambiente PUBSUB_EMULATOR_HOST e il relativo valore come indicato dall'output del comando env-init. Questa configurazione connette l'applicazione all'emulatore. Facoltativamente, puoi impostare l'ambiente PUBSUB_PROJECT_ID per il progetto che vuoi utilizzare per l'emulatore.

    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

La tua applicazione si connetterà all'emulatore Pub/Sub.

Nota: se utilizzi il server di sviluppo locale di Python App Engine Standard, devi passare questa variabile di ambiente nella riga di comando come segue:

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

dev_appserver.py è incluso in [PATH_TO_CLOUD_SDK]/google-cloud-sdk/bin/dev_appserver.py.

Utilizzo dell'emulatore

Per utilizzare l'emulatore, devi avere un'applicazione creata utilizzando le librerie client di Cloud. L'emulatore non supporta la console Google Cloud o gcloud pubsub tramite comandi SQL.

L'esempio seguente mostra l'uso dell'emulatore e di un'applicazione che utilizza Libreria client Cloud Python per eseguire varie operazioni. Esempi di queste operazioni includono: creare un argomento, pubblicare e leggere messaggi.

Completa i seguenti passaggi sulla macchina in cui hai impostato l'emulatore variabili di ambiente:

  1. Recupera gli esempi Python di Pub/Sub da GitHub clonando l'intero repository Python.

  2. Nel repository clonato, vai alla directory samples/snippets. I passaggi rimanenti sono completati in questa directory.

  3. Dalla directory samples/snippets, installa le dipendenze necessarie per eseguire l'esempio:

    pip install -r requirements.txt
    
  4. Crea un argomento:

     python publisher.py PUBSUB_PROJECT_ID create TOPIC_ID
    
  5. (Facoltativo) Se non hai un endpoint push locale per testare le iscrizioni push nell'emulatore, completa i seguenti passaggi per crearne uno suhttp://[::1]:3000/messages.

    1. Installa JSON Server.
      npm install -g json-server
      
    2. Avvia JSON Server.
      json-server --port 3000 --watch db.json
      
      dove db.json contiene il seguente codice di avvio:
      {
         "messages": []
      }
      
    3. Nel prossimo passaggio, annota http://[::1]:3000/messages per PUSH_ENDPOINT.
  6. Crea una sottoscrizione per l'argomento:

    • Crea una sottoscrizione pull:

      python subscriber.py PUBSUB_PROJECT_ID create TOPIC_ID SUBSCRIPTION_ID
      
    • Crea una sottoscrizione push:

      python subscriber.py PUBSUB_PROJECT_ID create-push TOPIC_ID SUBSCRIPTION_ID \
      PUSH_ENDPOINT
      
  7. Pubblica messaggi nell'argomento:

     python publisher.py PUBSUB_PROJECT_ID publish TOPIC_ID
    
  8. Leggi i messaggi pubblicati nell'argomento:

    • Recupera i messaggi dalla sottoscrizione pull:

      python subscriber.py PUBSUB_PROJECT_ID receive SUBSCRIPTION_ID
      
    • Osserva i messaggi inviati al tuo endpoint push locale. Ad esempio, i messaggi hanno questo aspetto:

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

Accesso alle variabili di ambiente

In tutti i linguaggi, ad eccezione di Java e C#, se hai impostato PUBSUB_EMULATOR_HOST come descritto in Impostare le variabili di ambiente, le librerie client di Pub/Sub chiamano automaticamente l'API in esecuzione locale anziché Pub/Sub.

Tuttavia, le librerie client C# e Java richiedono di modificare il codice per utilizzare l'emulatore:

C#

Prima di provare questo esempio, segui le istruzioni per la configurazione di C# nel Guida rapida di Pub/Sub con librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub C#.

Per autenticarti a Pub/Sub, configura le credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.


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

Prima di provare questo esempio, segui le istruzioni per la configurazione di Java nel Guida rapida di Pub/Sub con librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API Pub/Sub Java.

Per eseguire l'autenticazione su Pub/Sub, configura le credenziali predefinite dell'applicazione. Per maggiori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.


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;
import java.io.IOException;

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

Arresto dell'emulatore

Per arrestare l'emulatore, premi Ctrl+C.

Dopo aver interrotto l'emulatore, esegui il seguente comando per rimuovere la variabile di ambiente PUBSUB_EMULATOR_HOST in modo che l'applicazione si connetta a Pub/Sub:

Linux / MacOS
unset PUBSUB_EMULATOR_HOST
Windows
set PUBSUB_EMULATOR_HOST=

Argomenti della riga di comando dell'emulatore

Per maggiori dettagli sugli argomenti della riga di comando per l'emulatore Pub/Sub, consulta gcloud beta emulators pubsub

Funzionalità supportate

L'emulatore supporta le seguenti funzionalità Pub/Sub:

  • Pubblicazione di messaggi
  • Ricezione di messaggi da sottoscrizioni push e pull
  • Ordinamento dei messaggi
  • Ripetizione della visione dei messaggi
  • Inoltro di messaggi ad argomenti messaggi non recapitabili
  • Nuovi criteri per la consegna dei messaggi
  • Supporto dello schema per Avro

Limitazioni note

  • Le RPC UpdateTopic e UpdateSnapshot non sono supportate.
  • Le operazioni IAM non sono supportate.
  • La conservazione dei messaggi configurabile non è supportata; tutti i messaggi vengono conservati indefinitamente.
  • La scadenza dell'abbonamento non è supportata. Gli abbonamenti non hanno scadenza.
  • I filtri non sono supportati.
  • Supporto dello schema per i buffer di protocollo.
  • È possibile creare sottoscrizioni BigQuery, ma non inviare messaggi a BigQuery.
  • La ricerca fino a un timestamp per le sottoscrizioni ordinate non è supportata.

Per segnalare i problemi, utilizza lo strumento Issue Tracker pubblico.

Passaggi successivi

  • Per scoprire come utilizzare l'emulatore Pub/Sub con minikube, consulta questo post del blog.