google-app-enginegoogle-cloud-pubsubgoogle-cloud-pubsub-emulator

Does the Google PubSub Emulator work with the Google Cloud Pub/Sub API Client Library?


Our Java app runs on Google App Engine. It is using Google's PubSub to publish and consume messages.

There are two Java clients for Google PubSub. The gRPC client is recommended, but as stated at the bottom of this page https://cloud.google.com/pubsub/grpc-overview is not supported on Google App Engine.

The other library is the Google Cloud Pub/Sub API Client - https://developers.google.com/api-client-library/java/apis/pubsub/v1

When using the gRPC client lib it was easy to get working with the pubsub emulator. Just set an environment property and done.

Does the PubSub API client work with the Google PubSub emulator?

Our goal when running our application locally is to be able to use the PubSub emulator instead of connecting to a live instance in the cloud.


Solution

  • This works but the PubSub client needs to be configured correctly against the port the emulator is using.

    This is the code I use to create the PubSub client. It is based on PubSub Sample . Notice the setRootUrl part.

    private Pubsub getClient(final HttpTransport httpTransport, final JsonFactory jsonFactory) {
        Preconditions.checkNotNull(httpTransport);
        Preconditions.checkNotNull(jsonFactory);
        GoogleCredential credential = null;
        try {
            credential = GoogleCredential.getApplicationDefault();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (credential.createScopedRequired()) {
            credential = credential.createScoped(PubsubScopes.all());
        }
        // Please use custom HttpRequestInitializer for automatic
        // retry upon failures.
        HttpRequestInitializer initializer = new RetryHttpInitializerWrapper(credential);
        Pubsub.Builder pubsubBuilder = new Pubsub.Builder(httpTransport, jsonFactory, initializer);
        pubsubBuilder.setApplicationName("<your project id>");
        //Check if this is localhost
        if (SystemProperty.environment.value() != SystemProperty.Environment.Value.Production) {
            pubsubBuilder.setRootUrl("http://localhost:8321/");
        }
        return pubsubBuilder.build();
    }
    

    Then start the emulator by using:

    gcloud beta emulators pubsub start --host-port=localhost:8321

    Actual port number is not important. Then of course the topics and subscriptions need to be configured by code every time you restart the emulator.