[JAVA] GCP: Link Functions and Pub / Sub

Preface

I tried using Pub / Sub as a way to call another Functions from Google Cloud Functions.

Constitution

Try

What is Pub / Sub?

Messaging and ingesting for event-driven systems and streaming analytics. Cloud Pub/Sub  |  Google Cloud

Pub / Sub is an asynchronous messaging service that separates the service that handles events from the service that generates events. Pub/What is Sub|  Cloud Pub/Sub document|  Google Cloud

The official document is easy to understand the relationship between terms and characters. Publisher-Subscriber Relationships (https://cloud.google.com/pubsub/docs/overview?hl=ja#publisher-subscriber-relationships)

The general flow is as follows.

  1. Create a topic in advance
  2. Publisher (so-called caller) publishes a message (data) on a topic
  3. The subscriber (the so-called callee) creates the subscription and receives the message
  4. Subscription ends when all messages are received

Publishers and subscribers can be freely configured, such as one-to-many or many-to-many instead of one-to-one.

Run on GCP

Rough procedure

  1. Create a topic in Pub / Sub
  2. Create a Pub / Sub trigger in Functions
  3. Create Functions to publish the message on the topic

3 HTTP Triggers-> 1 Topic-> 2 Functions It becomes the flow.

1. Create a topic in Pub / Sub

"Create a topic" from the GCP console> Pub / Sub> topics. Set any character string for the topic ID.

2. Create a Pub / Sub trigger in Functions

"Create a function" from GCP Console> Cloud Functions. Set the trigger type to Cloud Pub / Sub, select the topic created in 1, and save the configuration.

Choose the code runtime you like. This time it's Java 11.

Validation of subscribe (Pub / Sub-> Functions)

Once you've set this up, go back to the Pub / Sub topic in 1 and make sure it's triggered. Open the topic in the GCP Console> Pub / Sub> topics and "Publish Message". I just want to check it, so add the message "once" in "Publish one message".

Open the "log" for the target function in GCP Console> Cloud Functions. If all goes well, you'll see a message published like this. image.png

3. Create Functions to publish the message on the topic

I made it with gradle, referring to the source of the official document. Publish a message to a topic|  Cloud Pub/Sub  |  Google Cloud

PublishFunction.java


import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.protobuf.ByteString;
import com.google.cloud.pubsub.v1.Publisher;
import com.google.pubsub.v1.ProjectTopicName;
import com.google.pubsub.v1.PubsubMessage;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutionException;

public class PublishFunction implements HttpFunction {
    private static final String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT");
    private static final String TOPIC_NAME = System.getenv("GOOGLE_CLOUD_PUBSUB_TOPIC");

    @Override
    public void service(HttpRequest request, HttpResponse response) throws Exception {
        String message = request.getFirstQueryParameter("message").get();
        ByteString byteStr = ByteString.copyFrom(message, StandardCharsets.UTF_8);
        PubsubMessage pubsubApiMessage = PubsubMessage.newBuilder().setData(byteStr).build();

        try {
            Publisher publisher = Publisher.newBuilder(ProjectTopicName.of(PROJECT_ID, TOPIC_NAME)).build();
            try {
                publisher.publish(pubsubApiMessage).get();
                response.setStatusCode(200);
                response.getWriter().write(message);
            } finally {
                publisher.shutdown();
                publisher.awaitTermination(1, TimeUnit.MINUTES);
            }
        } catch (InterruptedException | ExecutionException e) {
            System.out.println("Error publishing Pub/Sub message: " + e.getMessage());
            response.setStatusCode(500);
            response.getWriter().write(message);
        }
    }
}

Set the following

build.gradle


dependencies {
	implementation platform("com.google.cloud:libraries-bom:5.3.0");
	implementation("com.google.cloud:google-cloud-pubsub");
	implementation('com.google.protobuf:protobuf-java:3.13.0')
}

Register the created source in Functions (deployed from Cloud Build). The trigger type should be HTTP.

You also need to set the runtime variable GOOGLE_CLOUD_PROJECT. The TOPIC_NAME can be written directly in the code, but this time it was set as a runtime variable. Use of environment variables | Documents about Google Cloud Functions

Publish (Functions-> Pub / Sub) Verification

Call the HTTP trigger of the function created in 3. Since the URL parameter message can be passed, set any character here. If this is published as a message to Pub / Sub in 1 and finally output to the function in 2, it is successful.

Try locally

Even if I set the environment variable of GOOGLE_APPLICATION_CREDENTIALS locally, the following exception occurs. I don't know how to do it here: thinking:

java.io.IOException: The Application Default Credentials are not available. 
They are available if running in Google Compute Engine. 
Otherwise, the environment variable GOOGLE_APPLICATION_CREDENTIALS must be defined pointing to a file defining the credentials. 
See https://developers.google.com/accounts/docs/application-default-credentials for more information.

Finally

I arrived at Pub / Sub, looking for what would be good for linking Functions. Functions are charged for startup time, so it seems convenient to be able to process them asynchronously.

Recommended Posts

GCP: Link Functions and Pub / Sub
GCP: Repeat from Pub / Sub to Cloud Functions, Cloud Functions to Pub / Sub
Higher-order functions and decorators
Anonymous and map functions
Link Hatena Bookmark and Yammer
React and Flask to GCP
Python 3 sorted and comparison functions
Class inheritance and super functions
Emulate GCP Cloud functions locally
Python higher-order functions and comprehensions