[[google-cloud-functions]]
= Google Cloud Functions
:page-aliases: adapters/gcp.adoc
The Google Cloud Functions adapter enables Spring Cloud Function apps to run on the https://cloud.google.com/functions[Google Cloud Functions] serverless platform.
You can either run the function locally using the open source https://github.com/GoogleCloudPlatform/functions-framework-java[Google Functions Framework for Java] or on GCP.
[[project-dependencies]]
== Project Dependencies
Start by adding the `spring-cloud-function-adapter-gcp` dependency to your project.
[source, xml]
----
org.springframework.cloud
spring-cloud-function-adapter-gcp
...
----
In addition, add the `spring-boot-maven-plugin` which will build the JAR of the function to deploy.
NOTE: Notice that we also reference `spring-cloud-function-adapter-gcp` as a dependency of the `spring-boot-maven-plugin`. This is necessary because it modifies the plugin to package your function in the correct JAR format for deployment on Google Cloud Functions.
[source, xml]
----
org.springframework.boot
spring-boot-maven-plugin
target/deploy
org.springframework.cloud
spring-cloud-function-adapter-gcp
----
Finally, add the Maven plugin provided as part of the Google Functions Framework for Java.
This allows you to test your functions locally via `mvn function:run`.
NOTE: The function target should always be set to `org.springframework.cloud.function.adapter.gcp.GcfJarLauncher`; this is an adapter class which acts as the entry point to your Spring Cloud Function from the Google Cloud Functions platform.
[source,xml]
----
com.google.cloud.functions
function-maven-plugin
0.9.1
org.springframework.cloud.function.adapter.gcp.GcfJarLauncher
8080
----
A full example of a working `pom.xml` can be found in the https://github.com/spring-cloud/spring-cloud-function/blob/master/spring-cloud-function-samples/function-sample-gcp-http/pom.xml[Spring Cloud Functions GCP sample].
[[http-functions]]
== HTTP Functions
Google Cloud Functions supports deploying https://cloud.google.com/functions/docs/writing/http[HTTP Functions], which are functions that are invoked by HTTP request. The sections below describe instructions for deploying a Spring Cloud Function as an HTTP Function.
[[getting-started]]
== Getting Started
Let’s start with a simple Spring Cloud Function example:
[source, java]
----
@SpringBootApplication
public class CloudFunctionMain {
public static void main(String[] args) {
SpringApplication.run(CloudFunctionMain.class, args);
}
@Bean
public Function uppercase() {
return value -> value.toUpperCase();
}
}
----
Specify your configuration main class in `resources/META-INF/MANIFEST.MF`.
[source]
----
Main-Class: com.example.CloudFunctionMain
----
Then run the function locally.
This is provided by the Google Cloud Functions `function-maven-plugin` described in the project dependencies section.
----
mvn function:run
----
Invoke the HTTP function:
----
curl http://localhost:8080/ -d "hello"
----
== Build & Deploy to GCP
Start by packaging your application.
----
mvn package
----
If you added the custom `spring-boot-maven-plugin` plugin defined above, you should see the resulting JAR in `target/deploy` directory.
This JAR is correctly formatted for deployment to Google Cloud Functions.
Next, make sure that you have the https://cloud.google.com/sdk/install[Cloud SDK CLI] installed.
From the project base directory run the following command to deploy.
----
gcloud functions deploy function-sample-gcp-http \
--entry-point org.springframework.cloud.function.adapter.gcp.GcfJarLauncher \
--runtime java11 \
--trigger-http \
--source target/deploy \
--memory 512MB
----
Invoke the HTTP function:
----
curl https://REGION-PROJECT_ID.cloudfunctions.net/function-sample-gcp-http -d "hello"
----
Setting custom HTTP statusCode:
----
Functions can specify a custom HTTP response code by setting the `FunctionInvoker.HTTP_STATUS_CODE` header.
----
[source, java]
----
@Bean
public Function> function() {
String payload = "hello";
Message message = MessageBuilder.withPayload(payload).setHeader(FunctionInvoker.HTTP_STATUS_CODE, 404).build();
return input -> message;
};
----
[[background-functions]]
== Background Functions
Google Cloud Functions also supports deploying https://cloud.google.com/functions/docs/writing/background[Background Functions] which are invoked indirectly in response to an event, such as a message on a https://cloud.google.com/pubsub[Cloud Pub/Sub] topic, a change in a https://cloud.google.com/storage[Cloud Storage] bucket, or a https://firebase.google.com/[Firebase] event.
The `spring-cloud-function-adapter-gcp` allows for functions to be deployed as background functions as well.
The sections below describe the process for writing a Cloud Pub/Sub topic background function.
However, there are a number of different event types that can trigger a background function to execute which are not discussed here; these are described in the https://cloud.google.com/functions/docs/calling[Background Function triggers documentation].
== GCP Getting Started
Let’s start with a simple Spring Cloud Function which will run as a GCF background function:
[source, java]
----
@SpringBootApplication
public class BackgroundFunctionMain {
public static void main(String[] args) {
SpringApplication.run(BackgroundFunctionMain.class, args);
}
@Bean
public Consumer pubSubFunction() {
return message -> System.out.println("The Pub/Sub message data: " + message.getData());
}
}
----
In addition, create `PubSubMessage` class in the project with the below definition.
This class represents the https://cloud.google.com/functions/docs/calling/pubsub#event_structure[Pub/Sub event structure] which gets passed to your function on a Pub/Sub topic event.
[source, java]
----
public class PubSubMessage {
private String data;
private Map attributes;
private String messageId;
private String publishTime;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Map getAttributes() {
return attributes;
}
public void setAttributes(Map attributes) {
this.attributes = attributes;
}
public String getMessageId() {
return messageId;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public String getPublishTime() {
return publishTime;
}
public void setPublishTime(String publishTime) {
this.publishTime = publishTime;
}
}
----
Specify your configuration main class in `resources/META-INF/MANIFEST.MF`.
[source]
----
Main-Class: com.example.BackgroundFunctionMain
----
Then run the function locally.
This is provided by the Google Cloud Functions `function-maven-plugin` described in the project dependencies section.
----
mvn function:run
----
Invoke the HTTP function:
----
curl localhost:8080 -H "Content-Type: application/json" -d '{"data":"hello"}'
----
Verify that the function was invoked by viewing the logs.
[[deploy-to-gcp]]
== Deploy to GCP
In order to deploy your background function to GCP, first package your application.
----
mvn package
----
If you added the custom `spring-boot-maven-plugin` plugin defined above, you should see the resulting JAR in `target/deploy` directory.
This JAR is correctly formatted for deployment to Google Cloud Functions.
Next, make sure that you have the https://cloud.google.com/sdk/install[Cloud SDK CLI] installed.
From the project base directory run the following command to deploy.
----
gcloud functions deploy function-sample-gcp-background \
--entry-point org.springframework.cloud.function.adapter.gcp.GcfJarLauncher \
--runtime java11 \
--trigger-topic my-functions-topic \
--source target/deploy \
--memory 512MB
----
Google Cloud Function will now invoke the function every time a message is published to the topic specified by `--trigger-topic`.
For a walkthrough on testing and verifying your background function, see the instructions for running the https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-gcp-background/[GCF Background Function sample].
[[sample-functions]]
== Sample Functions
The project provides the following sample functions as reference:
* The https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-gcp-http/[function-sample-gcp-http] is an HTTP Function which you can test locally and try deploying.
* The https://github.com/spring-cloud/spring-cloud-function/tree/master/spring-cloud-function-samples/function-sample-gcp-background/[function-sample-gcp-background] shows an example of a background function that is triggered by a message being published to a specified Pub/Sub topic.