-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cee1b75
commit 1a78986
Showing
27 changed files
with
1,186 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,313 @@ | ||
//// | ||
This guide is maintained in the main Quarkus repository | ||
and pull requests should be submitted there: | ||
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc | ||
//// | ||
= Quarkus - Funqy Google Cloud Functions | ||
:extension-status: preview | ||
|
||
include::./attributes.adoc[] | ||
|
||
The guide walks through quickstart code to show you how you can deploy Funqy functions to Google Cloud Functions. | ||
|
||
include::./status-include.adoc[] | ||
|
||
== Prerequisites | ||
|
||
To complete this guide, you need: | ||
|
||
* less than 30 minutes | ||
* JDK 11 (Google Cloud Functions requires JDK 11) | ||
* Apache Maven {maven-version} | ||
* https://cloud.google.com/[A Google Cloud Account]. Free accounts work. | ||
* https://cloud.google.com/sdk[Cloud SDK CLI Installed] | ||
|
||
== Login to Google Cloud | ||
|
||
If you don't login to Google Cloud you won't be able to deploy. | ||
|
||
[source, subs=attributes+] | ||
---- | ||
gcloud auth login | ||
---- | ||
|
||
At the time writing this guide, Cloud Functions are still in beta so make sure to install the `beta` command group. | ||
|
||
[source, subs=attributes+] | ||
---- | ||
gcloud components install beta | ||
---- | ||
|
||
== The Code | ||
|
||
There is nothing special about the code and more importantly nothing Google Cloud specific. Funqy functions can be deployed to many different | ||
environments and Google Cloud Functions is one of them. The Java code is actually the same exact code as the {quickstarts-tree-url}/funqy-quickstarts/funqy-http-quickstart[funqy-http-quickstart]. | ||
|
||
[[choose]] | ||
== Choose Your Function | ||
|
||
Only one Funqy function can be exported per Google Cloud Functions deployment. If you only have one method | ||
annotated with `@Funq` in your project, then there is no worries. If you have multiple functions defined | ||
within your project, then you will need to choose the function within your Quarkus `application.properties`: | ||
|
||
[source, subs=attributes+] | ||
---- | ||
quarkus.funqy.export=greet | ||
---- | ||
|
||
Alternatively, you can set the `QUARKUS_FUNQY_EXPORT` environment variable when you create the Google Cloud Function using the `gcloud` cli. | ||
|
||
== Build and Deploy | ||
|
||
Build the project using maven. | ||
|
||
[source, subs=attributes+] | ||
---- | ||
./mvnw clean package | ||
---- | ||
|
||
This will compile and package your code. | ||
|
||
|
||
== Create the function | ||
|
||
In this example, we will create 3 functions, an http function and two background functions. Background functions allow to | ||
react to Google Cloud events like PubSub messages, Cloud Storage events, Firestore events, ... | ||
|
||
[source,java] | ||
---- | ||
import javax.inject.Inject; | ||
import io.quarkus.funqy.Funq; | ||
import io.quarkus.funqy.function.event.PubsubMessage; | ||
import io.quarkus.funqy.function.event.StorageEvent; | ||
public class GreetingFunctions { | ||
@Inject | ||
GreetingService service; | ||
// <1> | ||
@Funq | ||
public Greeting helloHttpWorld() { | ||
String message = service.hello("world"); | ||
Greeting greeting = new Greeting(); | ||
greeting.setMessage(message); | ||
greeting.setName("world"); | ||
return greeting; | ||
} | ||
// <2> | ||
@Funq | ||
public void helloPubSubWorld(PubsubMessage pubSubEvent) { | ||
String message = service.hello("world"); | ||
System.out.println(pubSubEvent.messageId + " - " + message); | ||
} | ||
// <3> | ||
@Funq | ||
public void helloGCSWorld(StorageEvent storageEvent) { | ||
String message = service.hello("world"); | ||
System.out.println(storageEvent.name + " - " + message); | ||
} | ||
} | ||
---- | ||
|
||
NOTE: Function return type can also be Mutiny reactive types. | ||
|
||
1. This is an HTTP function | ||
2. This is a background function that takes as parameter a `io.quarkus.funqy.function.event.PubsubMessage`, | ||
this is a convenient class to deserialize a PubSub message. | ||
3. This is a background function that takes as parameter a `io.quarkus.funqy.function.event.StorageEvent`, | ||
this is a convenient class to deserialize a Google Storage event. | ||
|
||
NOTE: we provide convenience class to deserialize common Google Cloud event inside the `io.quarkus.funqy.function.event` package. | ||
They are not mandatory to use, you can use any object you want. | ||
|
||
As our project contains multiple function, we need to specify wich function needs to be deployed via the following property inside our `application.properties` : | ||
|
||
[source,property] | ||
---- | ||
quarkus.funqy.export=helloHttpWorld | ||
---- | ||
|
||
== Build and Deploy to Google Cloud | ||
|
||
To build your application, you first need to define a packaging of type `uber-jar` via your `application.properties`. | ||
|
||
[source] | ||
---- | ||
quarkus.package.uber-jar=true | ||
---- | ||
|
||
Then you can package your application via `mvn clean package`. | ||
You will have a single JAR inside the target repository that contains your classes and all your dependencies in it. | ||
|
||
To deploy your JAR to Google Cloud, you need to pass a directory with only this JAR inside it, to the gcloud utility. | ||
|
||
So first, create a `deployment` directory and copy the generated artifact inside it. | ||
|
||
[source] | ||
---- | ||
mkdir deployment | ||
cp target/funqy-google-cloud-functions-1.0-SNAPSHOT-runner.jar deployment/ | ||
---- | ||
|
||
Then you will be able to use `gcloud` to deploy your function to Google Cloud, the `gcloud` command will be different regarding which | ||
type of function you want to deploy (http or background), and for background function from which event you want to be triggered. | ||
|
||
|
||
=== Http Functions | ||
|
||
Use this command to deploy to Google Cloud Functions: | ||
|
||
[source] | ||
---- | ||
gcloud beta functions deploy quarkus-example-funky-http \ | ||
--entry-point=io.quarkus.funqy.function.FunqyHttpFunction \ | ||
--runtime=java11 --trigger-http --source=deployment | ||
---- | ||
|
||
The entry point always needs to be `io.quarkus.funqy.function.FunqyHttpFunction` as it will be this class | ||
that will bootstrap Quarkus. | ||
|
||
This command will give you as output a `httpsTrigger.url` that point to your function. | ||
|
||
=== Background Functions - PubSub | ||
|
||
Use this command to deploy to Google Cloud Functions: | ||
|
||
[source] | ||
---- | ||
gcloud beta functions deploy quarkus-example-funky-pubsub \ | ||
--entry-point=io.quarkus.funqy.function.FunqyBackgroundFunction \ | ||
--runtime=java11 --trigger-resource hello_topic --trigger-event google.pubsub.topic.publish \ | ||
--source=deployment | ||
---- | ||
|
||
The entry point always needs to be `io.quarkus.funqy.function.FunqyBackgroundFunction` as it will be this class | ||
that will bootstrap Quarkus. | ||
|
||
The `--trigger-resource` option defines the name of the PubSub topic, and the `--trigger-event google.pubsub.topic.publish` option | ||
define that this function will be triggered by all message publication inside the topic. | ||
|
||
To trigger an event to this function, you can use the `gcloud functions call` command: | ||
|
||
[source] | ||
---- | ||
gcloud functions call quarkus-example-funky-pubsub --data '{"data":"SGVsbG8sIFB1Yi9TdWIh"}' | ||
---- | ||
|
||
The `--data '{"data":"SGVsbG8sIFB1Yi9TdWIh"}'` option allow to specify the message to be send to PubSub, this needs to be BASE64 encoded. | ||
Here we send `Hello, Pub/Sub!`. | ||
|
||
=== Background Functions - Cloud Storage | ||
|
||
Before deploying your function, you need to create a bucket. | ||
|
||
[source] | ||
---- | ||
gsutil mb gs://quarkus-hello | ||
---- | ||
|
||
Then, use this command to deploy to Google Cloud Functions: | ||
|
||
[source] | ||
---- | ||
gcloud beta functions deploy quarkus-example-funky-storage \ | ||
--entry-point=io.quarkus.funqy.function.FunqyBackgroundFunction \ | ||
--runtime=java11 --trigger-resource quarkus-hello --trigger-event google.storage.object.finalize \ | ||
--source=deployment | ||
---- | ||
|
||
The entry point always needs to be `io.quarkus.funqy.function.FunqyBackgroundFunction` as it will be this class | ||
that will bootstrap Quarkus. | ||
|
||
The `--trigger-resource` option defines the name of the Cloud Storage bucket, and the `--trigger-event google.storage.object.finalize` option | ||
define that this function will be triggered by all new file inside this bucket. | ||
|
||
To trigger an event to this function, you can use the `gcloud functions call` command: | ||
|
||
[source] | ||
---- | ||
gcloud functions call quarkus-example-funky-pubsub --data '{"name":"test.txt"}' | ||
---- | ||
|
||
The `--data '{"name":"test.txt"}'` option allow to specify a fake file name, a fake Cloud Storage event will be created for this name. | ||
|
||
You can also simply add a file to Cloud Storage using the command line of the web console. | ||
|
||
== Testing locally | ||
|
||
The easiest way to locally test your function is using the Cloud Function invoker JAR. | ||
|
||
You can download it via Maven using the following command: | ||
|
||
[source] | ||
---- | ||
mvn dependency:copy \ | ||
-Dartifact='com.google.cloud.functions.invoker:java-function-invoker:1.0.0-beta1' \ | ||
-DoutputDirectory=. | ||
---- | ||
|
||
Then you can use it to launch your function locally, again, the command depends on the type of function and the type of events. | ||
|
||
=== Http Functions | ||
|
||
For HTTP functions, you launch the invoker with a target class of `io.quarkus.funqy.function.FunqyHttpFunction`. | ||
|
||
[source] | ||
---- | ||
java -jar java-function-invoker-1.0.0-beta1.jar \ | ||
--classpath target/funqy-google-cloud-functions-1.0-SNAPSHOT-runner.jar \ | ||
--target io.quarkus.funqy.function.FunqyHttpFunction | ||
---- | ||
|
||
Then you can call your HTTP function: | ||
|
||
[source] | ||
---- | ||
curl localhost:8080 | ||
> {"name":"world","message":"Hello world!"} | ||
---- | ||
|
||
=== Background Functions - PubSub | ||
|
||
For background functions, you launch the invoker with a target class of `io.quarkus.funqy.function.FunqyBackgroundFunction`. | ||
|
||
[source] | ||
---- | ||
java -jar java-function-invoker-1.0.0-beta1.jar \ | ||
--classpath target/funqy-google-cloud-functions-1.0-SNAPSHOT-runner.jar \ | ||
--target io.quarkus.funqy.function.FunqyBackgroundFunction | ||
---- | ||
|
||
Then you can call your background function via an HTTP call with a payload containing the event: | ||
|
||
[source] | ||
---- | ||
curl localhost:8080 -d '{"data":{"data":"hello"}}' | ||
---- | ||
|
||
This will call your PubSub background function with a PubSubMessage `{"data":"hello"}`. | ||
|
||
=== Background Functions - Cloud Storage | ||
|
||
For background functions, you launch the invoker with a target class of `io.quarkus.funqy.function.FunqyBackgroundFunction`. | ||
|
||
[source] | ||
---- | ||
java -jar java-function-invoker-1.0.0-beta1.jar \ | ||
--classpath target/funqy-google-cloud-functions-1.0-SNAPSHOT-runner.jar \ | ||
--target io.quarkus.funqy.function.FunqyBackgroundFunction | ||
---- | ||
|
||
Then you can call your background function via an HTTP call with a payload containing the event: | ||
|
||
[source] | ||
---- | ||
curl localhost:8080 -d '{"data":{"name":"text"}}' | ||
---- | ||
|
||
This will call your PubSub background function with a Cloud Storage event `{"name":"file.txt"}`, so an event on the `file.txt` file. |
48 changes: 48 additions & 0 deletions
48
extensions/funqy/funqy-google-cloud-function/deployment/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>quarkus-funqy-google-cloud-function-parent</artifactId> | ||
<groupId>io.quarkus</groupId> | ||
<version>999-SNAPSHOT</version> | ||
<relativePath>../</relativePath> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>quarkus-funqy-google-cloud-function-deployment</artifactId> | ||
<name>Quarkus - Funqy Google Cloud Function - Deployment</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-funqy-google-cloud-function</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-arc-deployment</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-funqy-server-common-deployment</artifactId> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-extension-processor</artifactId> | ||
<version>${project.version}</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
Oops, something went wrong.