Opzioni di deployment Java

Per il deployment di una funzione Java sono disponibili due opzioni:

Esegui il deployment dall'origine

Il codice sorgente della funzione deve trovarsi nella posizione abituale per i progetti Maven (src/main/java). Le funzioni di esempio in questo documento sono direttamente src/main/java, senza dichiarazione relativa al pacchetto nel file di origine .java. Per banale, probabilmente introdurresti un pacchetto. Se il pacchetto è com.example, la gerarchia sarebbe simile a questa:

myfunction/
├─ pom.xml
├─ src
    ├─main
        ├─ java
            ├─ com
                ├─ example
                    ├─ MyFunction.java

Utilizza il seguente comando per eseguire il deployment di una funzione HTTP:

gcloud functions deploy $name \
    --trigger-http \
    --gen2 \
    --region=REGION \
    --entry-point $function_class \
    --runtime java17 

Dove:

  • $name è un nome descrittivo arbitrario che sarà il nome del della funzione dopo il deployment. $name può contenere solo lettere, numeri trattini bassi e trattini.
  • $function_class è il nome completo del corso (ad esempio, com.example.MyFunction o solo MyFunction se non usi il pacchetto).

Utilizza il seguente comando per eseguire il deployment di una funzione basata su eventi:

gcloud functions deploy $name \
    --entry-point $function_class \
    --gen2 \
    --region=REGION \
    --trigger-resource $resource_name \
    --trigger-event $event_name \
    --runtime java17

Dove:

  • $name è un nome descrittivo arbitrario che sarà il nome del della funzione dopo il deployment.
  • $function_class è il nome completo del corso (ad esempio, com.example.MyFunction o solo MyFunction se non usi il pacchetto).
  • $resource_name e $event_name sono specifici per gli eventi che attivano la tua funzione basata su eventi. Esempi di risorse ed eventi supportati: Google Cloud Pub/Sub e Google Cloud Storage.

Durante il deployment di una funzione dall'origine, Google Cloud CLI carica dalla directory di origine (e tutti i contenuti al suo interno) a Google Cloud per la creazione. Da evitare invii file non necessari, puoi usare .gcloudignore file. Modifica il file .gcloudignore per ignorare le directory comuni, come .git e target/. Ad esempio, un .gcloudignore file può contenere quanto segue:

.git
target
build
.idea

Esegui il deployment da un JAR

Puoi eseguire il deployment di un JAR predefinito che contiene la funzione. È utile soprattutto se devi eseguire il deployment di una funzione che utilizza dipendenze da un repository privato di artefatti a cui non è possibile accedere di una pipeline di build dal codice sorgente. Il JAR può essere un JAR uber contiene la classe di funzione e tutte le sue classi di dipendenza o un modello JAR con Class-Path voci per i JAR di dipendenze in META-INF/MANIFEST.MF .

Crea ed esegui il deployment di un JAR Uber

Un'uber JAR è un file JAR che contiene le classi delle funzioni e tutte e delle sue dipendenze. Puoi creare un JAR Uber sia con Maven sia con Gradle. A eseguire il deployment di Uber JAR, deve essere l'unico file JAR nella sua directory, esempio:

my-function-deployment/
 ├─ my-function-with-all-dependencies.jar

Puoi copiare il file in questa struttura di directory oppure utilizzare Maven e Plug-in Gradle per generare la directory di deployment corretta.

Maven

Utilizza il plug-in Maven Shade per creare un JAR uber. Configura il tuo pom.xml con il plug-in Ombra:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals><goal>shade</goal></goals>
            <configuration>
              <outputFile>${project.build.directory}/deployment/${build.finalName}.jar</outputFile>
              <transformers>
                <!-- This may be needed if you need to shade a signed JAR -->
                <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
                  <resource>.SF</resource>
                  <resource>.DSA</resource>
                  <resource>.RSA</resource>
                </transformer>
                <!-- This is needed if you have dependencies that use Service Loader. Most Google Cloud client libraries does. -->
                <transformer implementation=
       "org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Crea l'uber JAR:

mvn package

quindi esegui il deployment con il comando seguente:

gcloud functions deploy jar-example \
    --gen2 \
    --entry-point=Example \
    --runtime=java17 \
    --region=REGION \
    --trigger-http \
    --source=target/deployment

Gradle

Usa il plug-in Shadow per Gradle. Configura il plug-in nel tuo File build.gradle:

buildscript {
   repositories {
       jcenter()
   }
   dependencies {
       ...
       classpath "com.github.jengelman.gradle.plugins:shadow:5.2.0"
   }
}

plugins {
   id 'java'
   ...
}
sourceCompatibility = '17.0'
targetCompatibility = '17.0'
apply plugin: 'com.github.johnrengelman.shadow'

shadowJar {
   mergeServiceFiles()
}
...

Ora puoi eseguire Gradle con il comando shadowJar:

gradle shadowJar

quindi esegui il deployment con il comando seguente:

gcloud functions deploy jar-example \
   --entry-point=Example \
   --runtime=java17 \
   --trigger-http \
   --source=build/libs

Crea ed esegui il deployment di un JAR thin con dipendenze esterne

Puoi creare ed eseguire il deployment di un file JAR sottile anziché di un JAR super. Un JAR sottile un file JAR che contiene solo le classi di funzione senza le dipendenze incorporate nello stesso file JAR. Poiché le dipendenze sono ancora necessarie devi configurare tutto come segue:

  • Le dipendenze devono trovarsi in una sottodirectory relativa al JAR di cui eseguire il deployment.
  • Il JAR deve avere un file META-INF/MANIFEST.MF che includa un Class-Path il cui valore elenca i percorsi di dipendenza richiesti.

Ad esempio, il file JAR my-function.jar ha un file META-INF/MANIFEST.MF con due dipendenze nella directory libs/ (un elenco di valori separati da spazi percorsi relativi):

Manifest-Version: 1.0
Class-Path: libs/dep1.jar libs/dep2.jar

La directory di deployment dovrebbe quindi contenere il file JAR della funzione principale, nonché una sottodirectory con le due dipendenze da cui dipende la funzione:

function-deployment/
├─ my-function.jar
├─ libs
       ├─ dep1.jar
       ├─ dep2.jar

Puoi creare un JAR sottile sia con Maven sia con Gradle:

Maven

Utilizza il plug-in Maven JAR per configurare automaticamente MANIFEST.MF con i percorsi alle dipendenze, quindi usa il plug-in Maven Dependency per copiarle.

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
  ...
  <build>
    ...
    <plugins>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>libs/</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <overWriteReleases>false</overWriteReleases>
              <includeScope>runtime</includeScope>
              <outputDirectory>${project.build.directory}/libs</outputDirectory>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>package</phase>
            <goals><goal>copy-resources</goal></goals>
            <configuration>
              <outputDirectory>${project.build.directory}/deployment</outputDirectory>
              <resources>
                <resource>
                  <directory>${project.build.directory}</directory>
                  <includes>
                    <include>${build.finalName}.jar</include>
                    <include>libs/**</include>
                  </includes>
                  <filtering>false</filtering>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

Crea un JAR sottile:

mvn package

quindi esegui il deployment con il comando seguente:

gcloud functions deploy jar-example \
--gen2 \
--region=REGION \
--entry-point=Example \
--runtime=java17 \
--trigger-http \
--source=target/deployment

Gradle

Aggiorna il file di progetto build.gradle per aggiungere una nuova attività per recuperare il delle dipendenze:

dependencies {
   // API available at compilation only, but provided at runtime
   compileOnly 'com.google.cloud.functions:functions-framework-api:1.0.1'
   // dependencies needed by the function
   // ...
}

jar {
 manifest {
   attributes(
     "Class-Path": provider {
         configurations.runtimeClasspath
           .collect { "libs/${it.name}" }.join(' ')
     }
   )
 }
}

task prepareDeployment(type: Copy) {
 into("${buildDir}/deployment")
 into('.') {
   from jar
 }
 into('libs') {
   from configurations.runtimeClasspath
 }
}