Connetti le applicazioni Java ad AlloyDB per PostgreSQL con l'autenticazione IAM

1. Prima di iniziare

Java e AlloyDB: connettività semplice e sicura

AlloyDB per PostgreSQL è il servizio di database completamente gestito e compatibile con PostgreSQL di Google Cloud per workload aziendali complessi. La connessione di un'applicazione Java ad AlloyDB in modo sicuro ed efficiente avviene tramite il connettore Java per AlloyDB (alloydb-jdbc-connector), una libreria client che va oltre un driver JDBC standard.

La magia del connettore Java per AlloyDB

alloydb-jdbc-connector funge da SocketFactory smart per il driver JDBC PostgreSQL standard (org.postgresql:postgresql). Astrae la creazione di una connessione sicura al database in modo che tu possa concentrarti sulla logica dell'applicazione anziché sulla sicurezza di rete o sulla rotazione delle credenziali:

  • Crittografia mTLS 1.3: stabilisce automaticamente una connessione TLS 1.3 con autenticazione reciproca tra la JVM e l'istanza AlloyDB senza richiedere la gestione manuale dei certificati client SSL/TLS.
  • Autorizzazione basata su IAM: anziché fare affidamento su password statiche del database, il connettore sfrutta Google Cloud IAM e le Credenziali predefinite dell'applicazione (ADC) per ottenere automaticamente token di accesso OAuth2 di breve durata.
  • PRIVATEPUBLICPSC Non è necessario impostare in modo hardcoded i nomi host o gli indirizzi IP, il che rende trasparenti i failover e la manutenzione.

Come funziona il connettore Java per AlloyDB

Prerequisiti

  • Familiarità con Java, Maven e i concetti di base di SQL/JDBC.
  • Familiarità di base con Google Cloud CLI (gcloud) e i ruoli IAM.

In questo lab proverai a:

  • Configura un'istanza AlloyDB e un service account per l'autenticazione del database IAM senza password.
  • Concedi le autorizzazioni per schemi e tabelle PostgreSQL con privilegio minimo a un'entità IAM.
  • Configura un DataSource di livello di produzione con JDBC semplice e HikariCP utilizzando SocketFactory di AlloyDB.
  • Integra il connettore Java per AlloyDB nelle applicazioni Spring Boot, Quarkus e Micronaut.
  • Registra AlloyDB SocketFactory per la compilazione di GraalVM Native Image e risolvi i problemi comuni di autenticazione IAM.

Che cosa ti serve

  • Un progetto Google Cloud con fatturazione abilitata e un cluster AlloyDB e un'istanza principale attivi (consulta la guida alla creazione di cluster AlloyDB o avvia un cluster AlloyDB Express in meno di due secondi).
  • I ruoli IAM roles/alloydb.admin e roles/resourcemanager.projectIamAdmin nel progetto.
  • Java 17 o versioni successive (consigliato Java 17 o 21 LTS) e Apache Maven installati.
  • CLI gcloud e client psql installati (o accesso a Google Cloud Shell).

2. Configura l'autenticazione IAM del database su AlloyDB

Prima di scrivere il codice Java, devi configurare l'istanza AlloyDB in modo che accetti i token IAM e creare l'identità IAM che la tua applicazione utilizzerà su tre livelli: Google Cloud IAM, il control plane di AlloyDB e il motore PostgreSQL.

Configurazione a tre livelli per l'autenticazione database AlloyDB IAM

Imposta le variabili di ambiente

Nel terminale, esporta le variabili corrispondenti al tuo progetto Google Cloud e all'istanza AlloyDB (sostituisci i segnaposto con i tuoi valori):

export PROJECT_ID="<PROJECT_ID>"
export REGION="europe-west1"
export CLUSTER_ID="<CLUSTER_ID>"
export INSTANCE_ID="<INSTANCE_ID>"
export DB_NAME="dvdrental"

Abilita le API richieste

Abilita le API AlloyDB, Compute Engine, Cloud Resource Manager, IAM e API Service Usage nel tuo progetto:

gcloud services enable \
    alloydb.googleapis.com \
    compute.googleapis.com \
    cloudresourcemanager.googleapis.com \
    iam.googleapis.com \
    serviceusage.googleapis.com \
    --project="${PROJECT_ID}"

Crea un service account e concedi i ruoli IAM

Crea un service account dedicato che fungerà da identità della tua applicazione Java:

gcloud iam service-accounts create java-alloydb-connector \
    --project="${PROJECT_ID}" \
    --display-name="Java Application DB Connector"

Concedi al service account i due ruoli IAM richiesti dal connettore Java per AlloyDB:

  1. roles/alloydb.client: obbligatorio per recuperare i metadati dell'istanza e richiedere certificati mTLS temporanei dall'API AlloyDB Admin.
  2. roles/serviceusage.serviceUsageConsumer: obbligatorio per l'autenticazione IAM del database.
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/alloydb.client"

gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/serviceusage.serviceUsageConsumer"

Abilita l'autenticazione IAM sull'istanza AlloyDB

Aggiorna i flag dell'istanza AlloyDB per impostare alloydb.iam_authentication=on. Questo è un flag dinamico e ha effetto immediato senza riavviare l'istanza:

gcloud alloydb instances update "${INSTANCE_ID}" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --database-flags=alloydb.iam_authentication=on

Registra l'utente del database IAM

Registra il service account come utente del database IAM_BASED nel tuo cluster AlloyDB utilizzando gcloud:

gcloud alloydb users create "java-alloydb-connector@${PROJECT_ID}.iam" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --type=IAM_BASED

Concedi le autorizzazioni per lo schema e la tabella PostgreSQL

Per impostazione predefinita, i nuovi utenti IAM del database non dispongono di privilegi per le tabelle. Connettiti all'istanza AlloyDB come utente amministratore postgres (tramite psql o AlloyDB Studio nella console Cloud) e concedi l'accesso al database e alle tabelle di destinazione (ad esempio il database di esempio DVD Rental):

-- Connect to your target database first
\c dvdrental

-- (Optional) Create a sample film table if your database is empty
CREATE TABLE IF NOT EXISTS public.film (
    film_id SERIAL PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    release_year INTEGER DEFAULT 2006,
    rating VARCHAR(10) DEFAULT 'PG',
    rental_rate NUMERIC(4,2) DEFAULT 2.99
);

INSERT INTO public.film (film_id, title, release_year, rating, rental_rate) VALUES
    (1, 'Academy Dinosaur', 2006, 'PG', 0.99),
    (2, 'Ace Goldfinger', 2006, 'G', 4.99),
    (3, 'Adaptation Holes', 2006, 'NC-17', 2.99),
    (4, 'Affair Prejudice', 2006, 'G', 2.99),
    (5, 'African Egg', 2006, 'G', 2.99)
ON CONFLICT (film_id) DO NOTHING;

-- Grant permissions to the IAM user (double quotes are required because of '@' and '.')
GRANT CONNECT ON DATABASE "dvdrental" TO "java-alloydb-connector@<PROJECT_ID>.iam";
GRANT USAGE ON SCHEMA public TO "java-alloydb-connector@<PROJECT_ID>.iam";
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO "java-alloydb-connector@<PROJECT_ID>.iam";

Quando esegui queste istruzioni in AlloyDB Studio (o psql), puoi ispezionare lo schema public.film e verificare le righe di esempio:

Concedi le autorizzazioni IAM e ispeziona public.film in AlloyDB Studio

Configura le Credenziali predefinite dell'applicazione (ADC) locali

Quando l'esecuzione avviene su Cloud Run, Google Kubernetes Engine (GKE) o Compute Engine, collega il service account java-alloydb-connector direttamente al workload. Quando esegui l'applicazione localmente sulla tua workstation, impersona il service account in modo che ADC generi token per quell'identità:

gcloud auth application-default login \
    --impersonate-service-account="java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com"

3. Connettiti con JDBC semplice e HikariCP

Per qualsiasi applicazione Java di livello di produzione, un pool di connessioni è essenziale e HikariCP è lo standard di settore. In questo passaggio, creerai una semplice applicazione JDBC + HikariCP che delega la creazione dei socket a com.google.cloud.alloydb.SocketFactory.

Crea il progetto Maven (pom.xml)

Crea una nuova directory jdbc-app con un file pom.xml contenente il driver JDBC PostgreSQL (42.7.14), il connettore Java per AlloyDB (1.4.0) e HikariCP (7.1.0):

mkdir -p jdbc-app/src/main/java
cd jdbc-app

Crea pom.xml:

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

    <groupId>com.example.alloydb</groupId>
    <artifactId>alloydb-jdbc-sample</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <exec.mainClass>AlloyDBConnectivity</exec.mainClass>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.14</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>alloydb-jdbc-connector</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>7.1.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.16</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.5.0</version>
                <configuration>
                    <cleanupDaemonThreads>false</cleanupDaemonThreads>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Crea AlloyDBConnectivity.java

Crea src/main/java/AlloyDBConnectivity.java (visualizza su GitHub Gist):

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class AlloyDBConnectivity {
    // Retrieve configuration from environment variables
    private static final String ALLOYDB_INSTANCE_URI = System.getenv("ALLOYDB_INSTANCE_NAME"); // e.g., projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>
    private static final String ALLOYDB_DB_NAME = System.getenv("ALLOYDB_DB"); // e.g., "dvdrental"
    private static final String ALLOYDB_USER = System.getenv("ALLOYDB_USER"); // e.g., "java-alloydb-connector@<PROJECT_ID>.iam"
    private static final String ALLOYDB_PASS = System.getenv("ALLOYDB_PASS"); // Database password if not using IAM auth

    public static HikariDataSource createDataSource() {
        HikariConfig config = new HikariConfig();

        // The JDBC URL does not need a host or port. The SocketFactory will resolve the IP address.
        config.setJdbcUrl(String.format("jdbc:postgresql:///%s", ALLOYDB_DB_NAME));
        config.setUsername(ALLOYDB_USER);

        // Only set the password if you are NOT using IAM authentication.
        if (System.getenv("ALLOYDB_ENABLE_IAM_AUTH") == null || !System.getenv("ALLOYDB_ENABLE_IAM_AUTH").equalsIgnoreCase("true")) {
            config.setPassword(ALLOYDB_PASS);
        }

        // 1. Set the SocketFactory to the AlloyDB Connector's implementation.
        config.addDataSourceProperty("socketFactory", "com.google.cloud.alloydb.SocketFactory");

        // 2. Tell the connector which AlloyDB instance to connect to.
        config.addDataSourceProperty("alloydbInstanceName", ALLOYDB_INSTANCE_URI);

        // 3. (Recommended) Enable IAM database authentication.
        if (System.getenv("ALLOYDB_ENABLE_IAM_AUTH") != null && System.getenv("ALLOYDB_ENABLE_IAM_AUTH").equalsIgnoreCase("true")) {
            config.addDataSourceProperty("alloydbEnableIAMAuth", "true");
        }

        // 4. (Optional) Specify IP type (e.g., "PRIVATE", "PUBLIC", "PSC"). Defaults to PRIVATE.
        String ipType = System.getenv("ALLOYDB_IP_TYPE");
        if (ipType != null) {
            config.addDataSourceProperty("alloydbIpType", ipType);
        }

        // Baseline HikariCP settings
        config.setMaximumPoolSize(10);
        config.setMinimumIdle(2);
        config.setConnectionTimeout(30000); // 30 seconds
        config.setIdleTimeout(600000);      // 10 minutes
        config.setMaxLifetime(1800000);     // 30 minutes

        return new HikariDataSource(config);
    }

    public static void main(String[] args) {
        String sql = "SELECT title, release_year FROM public.film ORDER BY film_id LIMIT 5";

        try (HikariDataSource pool = createDataSource();
             Connection conn = pool.getConnection();
             PreparedStatement stmt = conn.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            System.out.println("Successfully connected to AlloyDB via IAM! Sample films:");
            while (rs.next()) {
                System.out.printf(" - %s (%d)%n", rs.getString("title"), rs.getInt("release_year"));
            }
        } catch (SQLException e) {
            System.err.println("Database connection failed: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Anatomia di un URL JDBC di AlloyDB e configurazione di HikariCP

Esegui l'applicazione JDBC semplice

Esporta le variabili di ambiente per l'istanza AlloyDB (imposta ALLOYDB_IP_TYPE="PUBLIC" se ti connetti dall'esterno del VPC tramite IP pubblico o "PRIVATE"/"PSC" se ti trovi all'interno del VPC) ed esegui l'applicazione:

export ALLOYDB_INSTANCE_NAME="projects/${PROJECT_ID}/locations/${REGION}/clusters/${CLUSTER_ID}/instances/${INSTANCE_ID}"
export ALLOYDB_DB="${DB_NAME}"
export ALLOYDB_USER="java-alloydb-connector@${PROJECT_ID}.iam"
export ALLOYDB_ENABLE_IAM_AUTH="true"
export ALLOYDB_IP_TYPE="PRIVATE" # Set to PUBLIC if connecting over Public IP from a local laptop

mvn compile exec:java

Dovresti visualizzare un output simile al seguente:

[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@1998bf07
[AlloyDBConnectivity.main()] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
Successfully connected to AlloyDB via IAM! Sample films:
 - Academy Dinosaur (2006)
 - Ace Goldfinger (2006)
 - Adaptation Holes (2006)
 - Affair Prejudice (2006)
 - African Egg (2006)

Output del terminale dell'esempio di JDBC semplice e HikariCP

4. Connettiti con Spring Boot

Spring Boot semplifica la connettività al database configurando automaticamente un pool di connessioni HikariCP dalle proprietà dell'applicazione. L'integrazione del connettore Java per AlloyDB non richiede codice bean DataSource personalizzato.

Crea il progetto Spring Boot (pom.xml)

Crea una nuova directory spring-boot-app:

cd ..
mkdir -p spring-boot-app/src/main/java/com/example/alloydb
mkdir -p spring-boot-app/src/main/resources
cd spring-boot-app

Crea pom.xml con spring-boot-starter-jdbc (che include HikariCP), org.postgresql:postgresql e com.google.cloud:alloydb-jdbc-connector:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.0.5</version>
        <relativePath/>
    </parent>

    <groupId>com.example.alloydb</groupId>
    <artifactId>alloydb-spring-boot-sample</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.14</version>
        </dependency>

        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>alloydb-jdbc-connector</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Configura application.properties o le variabili di ambiente

Puoi configurare l'URL di connessione in src/main/resources/application.properties:

# No host or port is needed; the SocketFactory handles it.
spring.datasource.url=jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>&alloydbEnableIAMAuth=true
spring.datasource.username=java-alloydb-connector@<PROJECT_ID>.iam
# No password required when alloydbEnableIAMAuth is true

Per mantenere i file di origine completamente privi di ID progetto o nomi di istanze, puoi lasciare vuoto application.properties e fornire queste variabili di ambiente Spring Boot standard in fase di runtime:

Variabile di ambiente

Valore

SPRING_DATASOURCE_URL

jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects//locations//clusters//instances/&alloydbEnableIAMAuth=true

SPRING_DATASOURCE_USERNAME

java-alloydb-connector@.iam

Crea AlloyDbTestApplication.java

Crea src/main/java/com/example/alloydb/AlloyDbTestApplication.java (visualizza su GitHub Gist):

package com.example.alloydb;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;

@SpringBootApplication
public class AlloyDbTestApplication {

    public static void main(String[] args) {
        System.exit(SpringApplication.exit(SpringApplication.run(AlloyDbTestApplication.class, args)));
    }

    @Bean
    CommandLineRunner testConnection(JdbcTemplate jdbcTemplate) {
        return args -> {
            String result = jdbcTemplate.queryForObject("SELECT 'Connection Successful!'", String.class);
            System.out.println(">>> ALLOYDB STATUS: " + result);
        };
    }
}

Esegui l'applicazione Spring Boot

Esporta le variabili di ambiente ed esegui l'app con mvn spring-boot:run:

export SPRING_DATASOURCE_URL="jdbc:postgresql:///${DB_NAME}?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/${PROJECT_ID}/locations/${REGION}/clusters/${CLUSTER_ID}/instances/${INSTANCE_ID}&alloydbEnableIAMAuth=true"
export SPRING_DATASOURCE_USERNAME="java-alloydb-connector@${PROJECT_ID}.iam"

mvn spring-boot:run

Dovresti vedere:

>>> ALLOYDB STATUS: Connection Successful!

Configurazione automatica di Spring Boot e output di esecuzione in tempo reale

5. Connettiti con Quarkus, Micronaut e GraalVM Native Image

Poiché il connettore Java per AlloyDB opera a livello di driver JDBC, il passaggio da un framework Java cloud-native all'altro non modifica il modo in cui proteggi il traffico del database o gestisci le identità. Sia Quarkus che Micronaut eseguono il wrapping del driver JDBC sottostante e delegano la crittografia mTLS, la risoluzione degli IP dinamici e l'autenticazione IAM al connettore tramite ADC.

Framework Java cloud-native e immagini native GraalVM con AlloyDB

Configurazione di Quarkus (application.properties con Agroal)

In un'applicazione Quarkus (quarkus-agroal e quarkus-jdbc-postgresql), aggiungi com.google.cloud:alloydb-jdbc-connector:1.4.0 alle dipendenze e passa i parametri del connettore tramite quarkus.datasource.jdbc.additional-jdbc-properties in src/main/resources/application.properties:

quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=java-alloydb-connector@<PROJECT_ID>.iam
quarkus.datasource.jdbc.url=jdbc:postgresql:///dvdrental
quarkus.datasource.jdbc.additional-jdbc-properties.socketFactory=com.google.cloud.alloydb.SocketFactory
quarkus.datasource.jdbc.additional-jdbc-properties.alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>
quarkus.datasource.jdbc.additional-jdbc-properties.alloydbEnableIAMAuth=true

Configurazione di Micronaut (application.yml con HikariCP)

In un'applicazione Micronaut (micronaut-jdbc-hikari), aggiungi com.google.cloud:alloydb-jdbc-connector:1.4.0 e configura src/main/resources/application.yml:

datasources:
  default:
    url: jdbc:postgresql:///dvdrental?socketFactory=com.google.cloud.alloydb.SocketFactory&alloydbInstanceName=projects/<PROJECT_ID>/locations/<REGION>/clusters/<CLUSTER_ID>/instances/<INSTANCE_ID>&alloydbEnableIAMAuth=true
    username: java-alloydb-connector@<PROJECT_ID>.iam
    driver-class-name: org.postgresql.Driver

Registrazione del connettore per GraalVM Native Image

Quando compili la tua applicazione in un'immagine nativa GraalVM (con Spring Boot 3+, Quarkus o Micronaut), c'è un dettaglio importante: la reflection.

Il driver JDBC PostgreSQL crea un'istanza di com.google.cloud.alloydb.SocketFactory in modo dinamico in base al nome della classe utilizzando la riflessione. Per evitare che l'analisi statica di GraalVM rimuova la classe durante la compilazione nativa, registrala esplicitamente:

  • Spring Boot 3+: aggiungi @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class) alla tua applicazione principale o alla classe @Configuration:
    @SpringBootApplication
    @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class)
    public class AlloyDbTestApplication { ... }
    
  • Quarkus: aggiungi @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class) alla classe principale o a un bean CDI:
    @QuarkusMain
    @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class)
    public class QuarkusAlloyDbApp implements QuarkusApplication { ... }
    

6. Risolvi i problemi comuni relativi a IAM e alla connettività

Se riscontri un errore FATAL: password authentication failed for user o AlloyDB IAM authentication failed, verifica le seguenti quattro aree:

Cheat sheet per la risoluzione dei problemi di connettività e IAM di AlloyDB

1. Rimuovi .gserviceaccount.com dai nomi utente del database del service account

La causa più frequente degli errori di autenticazione IAM è l'invio dell'indirizzo email completo del service account come nome utente del database. AlloyDB formatta i nomi utente del database IAM in modo diverso a seconda del tipo di entità:

  • Per i service account IAM (rimuovi .gserviceaccount.com): se l'indirizzo email del tuo service account Google Cloud è java-alloydb-connector@.iam.gserviceaccount.com, devi rimuovere il suffisso .gserviceaccount.com e impostare il nome utente del database JDBC/AlloyDB su java-alloydb-connector@.iam.
  • Per gli account utente o i gruppi IAM (mantieni l'indirizzo email completo): se l'autenticazione avviene come utente umano di Google Workspace o Cloud Identity, utilizza l'indirizzo email completo senza modifiche (ad esempio, ).

2. Verifica come è stato creato l'utente del database

Hai registrato l'utente tramite gcloud alloydb users create --type=IAM_BASED (o console/Terraform)? La creazione di un utente con SQL non elaborato CREATE USER non funzionerà per l'autenticazione IAM perché AlloyDB limita GRANT alloydbiamuser al control plane.

3. Verifica l'identità ADC attiva

Assicurati che l'ambiente in cui è in esecuzione il processo Java sia effettivamente autenticato come entità IAM di destinazione:

  • Workstation locale (connessione come service account): esegui gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com in modo che ADC generi token per il service account anziché per la tua email personale.
  • Cloud Run/GKE: verifica che il service account sia collegato al workload e disponga sia di roles/alloydb.client sia di roles/serviceusage.serviceUsageConsumer.

4. Considera la propagazione IAM e il routing di rete

  • Ritardo di propagazione IAM: la propagazione delle associazioni delle policy IAM può richiedere 60-120 secondi. Se hai appena creato il service account o l'associazione dei ruoli, attendi un minuto e riprova.
  • Accesso alla rete VPC: per impostazione predefinita, il connettore Java per AlloyDB si connette all'IP PRIVATE dell'istanza. Se la tua applicazione viene eseguita su Cloud Run, configura il traffico VPC diretto in uscita (consigliato per una latenza e un costo inferiori rispetto ai connettori di accesso VPC serverless legacy) o connettiti tramite Private Service Connect (PSC). Se ti connetti da una macchina locale esterna al VPC, abilita l'IP pubblico nell'istanza e passa alloydbIpType=PUBLIC.

7. Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi non necessari e per rimuovere le identità IAM create durante questo codelab, esegui la pulizia delle risorse riportate di seguito.

1. Rimuovi l'utente del database AlloyDB IAM e il service account

Elimina l'utente del database IAM dal cluster AlloyDB e rimuovi il service account:

# Delete the IAM database user from AlloyDB
gcloud alloydb users delete "java-alloydb-connector@${PROJECT_ID}.iam" \
    --cluster="${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --quiet

# Remove IAM policy bindings
gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/alloydb.client"

gcloud projects remove-iam-policy-binding "${PROJECT_ID}" \
    --member="serviceAccount:java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/serviceusage.serviceUsageConsumer"

# Delete the Service Account
gcloud iam service-accounts delete \
    "java-alloydb-connector@${PROJECT_ID}.iam.gserviceaccount.com" \
    --project="${PROJECT_ID}" \
    --quiet

2. Reimposta le Credenziali predefinite dell'applicazione locali

Se hai configurato la simulazione dell'identità ADC locale, reimposta le credenziali locali sulla tua identità utente predefinita:

gcloud auth application-default login

3. (Facoltativo) Elimina il cluster AlloyDB

gcloud alloydb clusters delete "${CLUSTER_ID}" \
    --region="${REGION}" \
    --project="${PROJECT_ID}" \
    --force \
    --quiet

8. Complimenti

Hai completato il codelab e stabilito una connettività sicura e senza password da Java ad AlloyDB per PostgreSQL.

Cosa hai realizzato

  1. Configurato l'autenticazione del database IAM: creato un service account con privilegi minimi, abilitato alloydb.iam_authentication=on, registrato l'utente IAM nel cluster AlloyDB e concesso i privilegi della tabella PostgreSQL.
  2. Connessione con Plain JDBC e HikariCP: HikariConfig configurato con com.google.cloud.alloydb.SocketFactory per la crittografia mTLS 1.3 automatica, l'aggiornamento dei token IAM e la risoluzione dinamica degli IP.
  3. Framework cloud-native integrati: abbiamo configurato Spring Boot, Quarkus (Agroal) e Micronaut (HikariCP) senza boilerplate di pool di connessioni personalizzati, oltre a suggerimenti di riflessione per GraalVM Native Image.
  4. Padronanza della risoluzione dei problemi IAM: hai imparato a diagnosticare i problemi di formattazione dei nomi utente, di simulazione dell'identità ADC e di routing VPC.

Scopri di più