I tried using Pub / Sub as a way to call another Functions from Google Cloud Functions.
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.
Publishers and subscribers can be freely configured, such as one-to-many or many-to-many instead of one-to-one.
3 HTTP Triggers-> 1 Topic-> 2 Functions It becomes the flow.
"Create a topic" from the GCP console> Pub / Sub> topics. Set any character string for the topic ID.
"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.
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.
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
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.
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.
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