JVM-Sprachen

Sie können die Funktion in verschiedenen JVM-Sprachen wie Kotlin, Groovy oder Scala schreiben, sofern sie diesen Regeln entsprechen:

  • Die Funktion ist eine öffentliche Klasse, die eine der Funktionsschnittstellen (HttpFunction, BackgroundFunction oder RawBackgroundFunction) implementiert und über einen öffentlichen Konstruktor ohne Argumente verfügt.

  • Wenn Sie sie aus der Quelle bereitstellen:

    • Sie kann aus Maven erstellt werden.
    • Die Build-Datei enthält alle Plug-ins zur Erstellung kompilierter Klassen.
  • Wenn Sie sie aus einer vordefinierten JAR-Datei bereitstellen:

    • Sie können diese JAR-Datei mit beliebigen Build-Tools erstellen.
    • Die vordefinierte JAR-Datei muss eine FAT-JAR-Datei mit allen Abhängigkeitsklassen sein oder ihr Manifest muss einen Class-Path-Eintrag mit den relativen Speicherorten von JAR-Dateien mit diesen Abhängigkeitsklassen enthalten.

Beispiele für HTTP-Funktionen

Wenn Sie Ihre Funktion über eine HTTP(S)-Anfrage aufrufen möchten, verwenden Sie HTTP-Funktionen. In den folgenden Beispielen wird die Nachricht "Hello World!" ausgegeben.

Kotlin

import com.google.cloud.functions.HttpFunction
import com.google.cloud.functions.HttpRequest
import com.google.cloud.functions.HttpResponse
import java.io.IOException
import java.util.logging.Logger

class HelloWorld : HttpFunction {
    // Simple function to return "Hello World"
    @Throws(IOException::class)
    override fun service(request: HttpRequest, response: HttpResponse) {
        response.writer.write("Hello World!")
    }
}

Groovy

import com.google.cloud.functions.HttpFunction
import com.google.cloud.functions.HttpRequest
import com.google.cloud.functions.HttpResponse

class GroovyHelloWorld implements HttpFunction {
    @Override
    void service(HttpRequest request, HttpResponse response) {
        response.writer.write("Hello World!")
    }
}

Scala

class ScalaHelloWorld extends HttpFunction {
  override def service(httpRequest: HttpRequest, httpResponse: HttpResponse): Unit = {
    httpResponse.getWriter.write("Hello World!")
  }
}

pom.xml-Datei für HTTP-Beispiele

Hier sind die pom.xml-Dateien für die obigen Beispiele:

Kotlin

<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.functions</groupId>
  <artifactId>functions-kotlin-hello-world</artifactId>

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <kotlin.version>1.9.22</kotlin.version>
  </properties>

  <dependencies>
    <!-- Required for Function primitives -->
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.1.0</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib-jdk8</artifactId>
      <version>${kotlin.version}</version>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-test</artifactId>
      <version>${kotlin.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <!--
          Google Cloud Functions Framework Maven plugin

          This plugin allows you to run Cloud Functions Java code
          locally. Use the following terminal command to run a
          given function locally:

          mvn function:run -Drun.functionTarget=your.package.yourFunction
        -->
        <groupId>com.google.cloud.functions</groupId>
        <artifactId>function-maven-plugin</artifactId>
        <version>0.11.0</version>
        <configuration>
          <functionTarget>functions.HelloWorld</functionTarget>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.jetbrains.kotlin</groupId>
        <artifactId>kotlin-maven-plugin</artifactId>
        <version>${kotlin.version}</version>
        <executions>
          <execution>
            <id>compile</id>
            <phase>compile</phase>
            <goals>
              <goal>compile</goal>
            </goals>
            <configuration>
              <sourceDirs>
                <source>src/main/kotlin</source>
              </sourceDirs>
            </configuration>
          </execution>
          <execution>
            <id>test-compile</id>
            <phase>test-compile</phase>
            <goals>
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <jvmTarget>1.8</jvmTarget>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Groovy

<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.functions</groupId>
  <artifactId>functions-groovy-hello-world</artifactId>

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <groovy.version>3.0.20</groovy.version>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <artifactId>libraries-bom</artifactId>
        <groupId>com.google.cloud</groupId>
        <scope>import</scope>
        <type>pom</type>
        <version>26.32.0</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!-- Required for Function primitives -->
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- Required for groovy samples -->
    <dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>${groovy.version}</version>
      <type>pom</type>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <!--
          Google Cloud Functions Framework Maven plugin

          This plugin allows you to run Cloud Functions Java code
          locally. Use the following terminal command to run a
          given function locally:

          mvn function:run -Drun.functionTarget=your.package.yourFunction
        -->
        <groupId>com.google.cloud.functions</groupId>
        <artifactId>function-maven-plugin</artifactId>
        <version>0.11.0</version>
        <configuration>
          <functionTarget>functions.GroovyHelloWorld</functionTarget>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.codehaus.gmavenplus</groupId>
        <artifactId>gmavenplus-plugin</artifactId>
        <version>3.0.2</version>
        <executions>
          <execution>
            <id>groovy-compile</id>
            <phase>process-resources</phase>
            <goals>
              <goal>addSources</goal>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <!-- any version of Groovy \>= 1.5.0 should work here -->
            <version>${groovy.version}</version>
            <scope>runtime</scope>
            <type>pom</type>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

Scala

<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">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.functions</groupId>
  <artifactId>functions-scala-hello-world</artifactId>

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <artifactId>libraries-bom</artifactId>
        <groupId>com.google.cloud</groupId>
        <scope>import</scope>
        <type>pom</type>
        <version>26.32.0</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!-- Required for scala samples -->
    <dependency>
      <groupId>org.scala-lang</groupId>
      <artifactId>scala-library</artifactId>
      <version>2.13.5</version>
    </dependency>

    <!-- Required for Function primitives -->
    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.1.0</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <!--
          Google Cloud Functions Framework Maven plugin

          This plugin allows you to run Cloud Functions Java code
          locally. Use the following terminal command to run a
          given function locally:

          mvn function:run -Drun.functionTarget=your.package.yourFunction
        -->
        <groupId>com.google.cloud.functions</groupId>
        <artifactId>function-maven-plugin</artifactId>
        <version>0.11.0</version>
        <configuration>
          <functionTarget>functions.ScalaHelloWorld</functionTarget>
        </configuration>
      </plugin>
      <plugin>
        <groupId>net.alchim31.maven</groupId>
        <artifactId>scala-maven-plugin</artifactId>
        <version>4.4.1</version>
        <executions>
          <execution>
            <id>scala-compile</id>
            <phase>process-resources</phase>
            <goals>
              <goal>add-source</goal>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

HTTP-Funktionen bereitstellen

Kotlin

gcloud functions deploy kotlin-helloworld --entry-point functions.KotlinHelloWorld --runtime java17 --trigger-http --allow-unauthenticated --memory 512MB

Groovy

gcloud functions deploy groovy-helloworld --entry-point functions.GroovyHelloWorld --runtime java17 --trigger-http --allow-unauthenticated --memory 512MB

Scala

gcloud functions deploy scala-helloworld --entry-point functions.ScalaHelloWorld --runtime java17 --trigger-http --allow-unauthenticated --memory 512MB

Ereignisgesteuerte Funktionen – Beispiele

Sie verwenden ereignisgesteuerte Funktionen, wenn die Cloud Functions-Funktion indirekt als Reaktion auf ein asynchrones Ereignis wie eine Nachricht in einem Pub/Sub-Thema, eine Änderung in einem Cloud Storage-Bucket oder ein Firebase-Ereignis aufgerufen werden soll.

Es gibt zwei Arten von ereignisgesteuerten Funktionen: Hintergrundfunktionen und CloudEvent-Funktionen. In den JVM-Sprachen werden nur Hintergrundfunktionen unterstützt.

Kotlin

import com.google.cloud.functions.BackgroundFunction
import com.google.cloud.functions.Context
import functions.eventpojos.PubsubMessage
import java.nio.charset.StandardCharsets
import java.util.Base64
import java.util.logging.Logger

class KotlinHelloPubSub : BackgroundFunction<PubsubMessage> {
    override fun accept(message: PubsubMessage, context: Context) {
        // name's default value is "world"
        var name = "world"
        if (message?.data != null) {
            name = String(
                    Base64.getDecoder().decode(message.data!!.toByteArray(StandardCharsets.UTF_8)),
                    StandardCharsets.UTF_8)
        }
        LOGGER.info(String.format("Hello %s!", name))
        return;
    }

    companion object {
        private val LOGGER = Logger.getLogger(KotlinHelloPubSub::class.java.name)
    }
}

Bei der Entwicklung von Hintergrundfunktionen definieren Sie Klassen für die Ereignisse, die Ihre Funktionen auslösen. Das GSON-Marshalling funktioniert jedoch möglicherweise nicht standardmäßig für Kotlin, wenn Ihre Ereignisklasse nicht bestimmten Richtlinien entspricht.

In der Kotlin-Ereignisklasse müssen Attribute diesen Richtlinien entsprechen:

  • Sie können auf null gesetzt werden.
  • Ihnen ist kein Standardwert zugewiesen.
  • Sie sind keine delegierten Attribute.

Ein weiterer Ansatz ist, die Ereignisklassen in Java zu erstellen und sie aus der Kotlin-Funktionsklasse heraus zu verwenden.

Groovy

import com.google.cloud.functions.BackgroundFunction
import com.google.cloud.functions.Context
import functions.eventpojos.PubsubMessage
import java.nio.charset.StandardCharsets
import java.util.logging.Logger

class GroovyHelloPubSub implements BackgroundFunction<PubsubMessage> {
    private static final Logger LOGGER = Logger.getLogger(GroovyHelloPubSub.class.name)

    @Override
    void accept(PubsubMessage message, Context context) {
        // name's default value is "world"
        String name = "world"

        if (message?.data) {
             name = new String(Base64.decoder.decode(message.data), StandardCharsets.UTF_8)
        }

        LOGGER.info("Hello ${name}!")
        return
    }
}

Scala

import java.nio.charset.StandardCharsets
import java.util.Base64
import java.util.logging.Logger

import com.google.cloud.functions.{BackgroundFunction, Context}
import functions.eventpojos.PubsubMessage

class ScalaHelloPubSub extends BackgroundFunction[PubsubMessage] {

  val LOGGER = Logger.getLogger(this.getClass.getName)

  override def accept(message: PubsubMessage, context: Context): Unit = {
    // name's default value is "world"
    var name = "world"
    if (message != null && message.getData != null) {
      name = new String(Base64.getDecoder.decode(
        message.getData.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8)
    }
    LOGGER.info(String.format("Hello %s!", name))
  }
}

Hintergrundfunktionen bereitstellen

Kotlin

gcloud functions deploy kotlin-hello-pubsub --entry-point functions.KotlinHelloPubSub --runtime java17 --trigger-topic my-topic --allow-unauthenticated --memory 512MB

Groovy

gcloud functions deploy groovy-hello-pubsub --entry-point functions.GroovyHelloPubSub --runtime java17 --trigger-topic my-topic --allow-unauthenticated --memory 512MB

Scala

gcloud functions deploy scala-hello-pubsub --entry-point functions.ScalaHelloPubSub --runtime java17 --trigger-topic my-topic --allow-unauthenticated --memory 512MB

Beispiele für Hintergrundfunktionen testen

So können Sie die Beispiele für Hintergrundfunktionen testen:

  1. Veröffentlichen Sie eine Nachricht in Ihrem Pub/Sub-Thema, um die Funktion auszulösen:

    gcloud pubsub topics publish my-topic --message Flurry
  2. Sehen Sie sich die Logs an:

    gcloud functions logs read --limit 10

Sie sollten in etwa so etwas mit einer Nachricht mit dem Namen sehen, den Sie im Pub/Sub-Thema veröffentlicht haben:

D      my-function  ...  Function execution started
I      my-function  ...  Hello Flurry!
D      my-function  ...  Function execution took 39 ms, finished with status: 'ok'