Conectar aplicativos Java ao AlloyDB para PostgreSQL com autenticação do IAM

1. Antes de começar

Java e AlloyDB: conectividade simples e segura

O AlloyDB para PostgreSQL é o serviço de banco de dados totalmente gerenciado e compatível com PostgreSQL do Google Cloud para cargas de trabalho corporativas exigentes. Para conectar um aplicativo Java ao AlloyDB de forma segura e eficiente, use o conector Java do AlloyDB (alloydb-jdbc-connector), uma biblioteca de cliente que vai além de um driver JDBC padrão.

A mágica do conector Java do AlloyDB

O alloydb-jdbc-connector funciona como um SocketFactory inteligente para o driver JDBC padrão do PostgreSQL (org.postgresql:postgresql). Ele abstrai o estabelecimento de uma conexão segura com o banco de dados para que você possa se concentrar na lógica do aplicativo, em vez de na segurança de rede ou na rotação de credenciais:

  • Criptografia mTLS 1.3: estabelece automaticamente uma conexão TLS 1.3 mutuamente autenticada entre a JVM e a instância do AlloyDB, sem que você precise gerenciar manualmente os certificados de cliente SSL/TLS.
  • Autorização baseada em IAM: em vez de usar senhas estáticas de banco de dados, o conector usa o Google Cloud IAM e o Application Default Credentials (ADC) para receber tokens de acesso OAuth2 de curta duração automaticamente.
  • Resolução de IP dinâmico: consulta a API AlloyDB Admin para resolver o endereço IP atual (PRIVATE, PUBLIC ou Private Service Connect PSC) da instância do banco de dados de forma dinâmica. Não é necessário codificar nomes de host ou endereços IP, o que torna os failovers e a manutenção transparentes.

Como o conector Java do AlloyDB funciona nos bastidores

Pré-requisitos

  • Familiaridade com Java, Maven e conceitos básicos de SQL/JDBC.
  • Familiaridade básica com a CLI do Google Cloud (gcloud) e os papéis do IAM.

Atividades deste laboratório

  • Configurar uma instância do AlloyDB e uma conta de serviço para a autenticação de banco de dados do IAM sem senha.
  • Conceder permissões de esquema e tabela do PostgreSQL com privilégio mínimo a um principal do IAM.
  • Configure um DataSource de nível de produção com JDBC simples e HikariCP usando o SocketFactory do AlloyDB.
  • Integre o conector Java do AlloyDB aos aplicativos Spring Boot, Quarkus e Micronaut.
  • Registrar o SocketFactory do AlloyDB para compilação de imagem nativa do GraalVM e resolver problemas comuns de autenticação do IAM.

O que é necessário

  • Um projeto na nuvem do Google Cloud com faturamento ativado e um cluster e uma instância principal do AlloyDB ativos (consulte o guia de criação de clusters do AlloyDB ou ative um cluster do AlloyDB Express em menos de dois segundos).
  • Os papéis do IAM roles/alloydb.admin e roles/resourcemanager.projectIamAdmin no projeto.
  • Java 17 ou mais recente (recomendamos o Java 17 ou 21 LTS) e o Apache Maven instalados.
  • CLI gcloud e cliente psql instalados (ou acesso ao Google Cloud Shell).

2. Configurar a autenticação de banco de dados do IAM no AlloyDB

Antes de escrever o código Java, é necessário configurar a instância do AlloyDB para aceitar tokens do IAM e criar a identidade do IAM que o aplicativo vai usar em três camadas: o IAM do Google Cloud, o plano de controle do AlloyDB e o mecanismo do PostgreSQL.

Configuração de três camadas para autenticação do banco de dados do IAM do AlloyDB

Definir variáveis de ambiente

No terminal, exporte as variáveis correspondentes ao projeto do Google Cloud e à instância do AlloyDB (substitua os marcadores de posição pelos seus valores):

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

Ativar APIs obrigatórias

Ative as APIs AlloyDB, Compute Engine, Cloud Resource Manager, IAM e API Service Usage no seu projeto:

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

Criar uma conta de serviço e conceder papéis do IAM

Crie uma conta de serviço dedicada que vai servir como a identidade do seu aplicativo Java:

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

Conceda à conta de serviço os dois papéis do IAM exigidos pelo conector Java do AlloyDB:

  1. roles/alloydb.client: necessário para buscar metadados de instância e solicitar certificados mTLS temporários da API AlloyDB Admin.
  2. roles/serviceusage.serviceUsageConsumer: obrigatório para a autenticação do banco de dados do IAM.
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"

Ativar a autenticação do IAM na instância do AlloyDB

Atualize as flags da instância do AlloyDB para definir alloydb.iam_authentication=on. Essa é uma flag dinâmica e entra em vigor imediatamente sem reiniciar a instância:

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

Registrar o usuário do banco de dados do IAM

Registre a conta de serviço como um usuário de banco de dados IAM_BASED no cluster do AlloyDB usando gcloud:

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

Conceder permissões de esquema e tabela do PostgreSQL

Por padrão, os usuários de banco de dados do IAM recém-criados não têm privilégios de tabela. Conecte-se à instância do AlloyDB como o usuário administrador postgres (usando psql ou o AlloyDB Studio no console do Cloud) e conceda acesso ao banco de dados e às tabelas de destino (como o banco de dados de amostra de locação de DVDs):

-- 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";

Ao executar essas instruções no AlloyDB Studio (ou psql), é possível inspecionar o esquema public.film e verificar as linhas de amostra:

Conceder permissões do IAM e inspecionar public.film no AlloyDB Studio

Configurar o Application Default Credentials (ADC) local

Ao executar no Cloud Run, no Google Kubernetes Engine (GKE) ou no Compute Engine, anexe a conta de serviço java-alloydb-connector diretamente à carga de trabalho. Ao executar localmente na estação de trabalho, use a identidade temporária da conta de serviço para que o ADC gere tokens para essa identidade:

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

3. Conectar-se com JDBC simples e HikariCP

Para qualquer aplicativo Java de nível de produção, um pool de conexões é essencial, e o HikariCP é o padrão do setor. Nesta etapa, você vai criar um aplicativo JDBC + HikariCP simples que delega a criação de soquetes para com.google.cloud.alloydb.SocketFactory.

Criar o projeto do Maven (pom.xml)

Crie um novo diretório jdbc-app com um arquivo pom.xml que contenha o driver JDBC do PostgreSQL (42.7.14), o conector Java do AlloyDB (1.4.0) e o HikariCP (7.1.0):

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

Crie 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>

Criar AlloyDBConnectivity.java

Crie src/main/java/AlloyDBConnectivity.java (confira no 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 de um URL JDBC do AlloyDB e da configuração do HikariCP

Executar o aplicativo JDBC simples

Exporte as variáveis de ambiente da instância do AlloyDB (defina ALLOYDB_IP_TYPE="PUBLIC" se estiver se conectando de fora da VPC por IP público ou "PRIVATE" / "PSC" quando estiver dentro da VPC) e execute o aplicativo:

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

Você verá uma saída como:

[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)

Saída do terminal do exemplo de JDBC simples e HikariCP

4. Conectar com o Spring Boot

O Spring Boot simplifica a conectividade do banco de dados ao configurar automaticamente um pool de conexões HikariCP com base nas propriedades do aplicativo. A integração do conector Java do AlloyDB não exige nenhum código de bean DataSource personalizado.

Criar o projeto do Spring Boot (pom.xml)

Crie um novo diretório 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

Crie pom.xml com spring-boot-starter-jdbc (que inclui 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>

Configurar application.properties ou variáveis de ambiente

É possível configurar o URL de conexão em 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

Para manter os arquivos de origem completamente livres de IDs de projeto ou nomes de instâncias, deixe application.properties vazio e forneça estas variáveis de ambiente padrão do Spring Boot no ambiente de execução:

Variável de ambiente

Valor

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

Criar AlloyDbTestApplication.java

Crie src/main/java/com/example/alloydb/AlloyDbTestApplication.java (confira no 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);
        };
    }
}

Executar o aplicativo Spring Boot

Exporte as variáveis de ambiente e execute o app com 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

Você verá:

>>> ALLOYDB STATUS: Connection Successful!

Configuração automática do Spring Boot e saída de execução em tempo real

5. Conectar-se com o Quarkus, o Micronaut e a imagem nativa do GraalVM

Como o conector Java do AlloyDB opera no nível do driver JDBC, alternar entre frameworks Java nativos da nuvem não muda a forma como você protege o tráfego do banco de dados ou gerencia identidades. O Quarkus e o Micronaut encapsulam o driver JDBC subjacente e delegam a criptografia mTLS, a resolução de IP dinâmico e a autenticação do IAM ao conector por meio do ADC.

Frameworks Java nativos da nuvem e imagem nativa do GraalVM com o AlloyDB

Configuração do Quarkus (application.properties com Agroal)

Em um aplicativo Quarkus (quarkus-agroal e quarkus-jdbc-postgresql), adicione com.google.cloud:alloydb-jdbc-connector:1.4.0 às suas dependências e transmita os parâmetros do conector por meio de quarkus.datasource.jdbc.additional-jdbc-properties em 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

Configuração do Micronaut (application.yml com HikariCP)

Em um aplicativo Micronaut (micronaut-jdbc-hikari), adicione com.google.cloud:alloydb-jdbc-connector:1.4.0 e configure 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

Como registrar o conector para a imagem nativa do GraalVM

Ao compilar seu aplicativo em uma imagem nativa do GraalVM (com Spring Boot 3+, Quarkus ou Micronaut), há um detalhe importante: Reflection.

O driver JDBC do PostgreSQL instancia com.google.cloud.alloydb.SocketFactory dinamicamente pelo nome da classe usando reflexão. Para evitar que a análise estática do GraalVM remova a classe durante a compilação nativa, registre-a explicitamente:

  • Spring Boot 3+: adicione @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class) ao aplicativo principal ou à classe @Configuration:
    @SpringBootApplication
    @RegisterReflectionForBinding(com.google.cloud.alloydb.SocketFactory.class)
    public class AlloyDbTestApplication { ... }
    
  • Quarkus: adicione @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class) à sua classe principal ou a um bean CDI:
    @QuarkusMain
    @RegisterForReflection(targets = com.google.cloud.alloydb.SocketFactory.class)
    public class QuarkusAlloyDbApp implements QuarkusApplication { ... }
    

6. Resolver problemas comuns de IAM e conectividade

Se você encontrar um erro FATAL: password authentication failed for user ou AlloyDB IAM authentication failed, verifique as quatro áreas a seguir:

Folha de referência para solução de problemas de IAM e conectividade do AlloyDB

1. Remover .gserviceaccount.com dos nomes de usuário do banco de dados da conta de serviço

A causa mais frequente de falhas de autenticação do IAM é transmitir o endereço de e-mail completo da conta de serviço como o nome de usuário do banco de dados. O AlloyDB formata os nomes de usuário do banco de dados do IAM de maneira diferente, dependendo do tipo de principal:

  • Para contas de serviço do IAM (remover .gserviceaccount.com): se o e-mail da sua conta de serviço do Google Cloud for java-alloydb-connector@.iam.gserviceaccount.com, você precisará remover o sufixo .gserviceaccount.com e definir o nome de usuário do banco de dados JDBC/AlloyDB como java-alloydb-connector@.iam.
  • Para contas de usuário ou grupos do IAM (mantenha o e-mail completo): se você estiver se autenticando como um usuário humano do Google Workspace ou do Cloud Identity, use seu endereço de e-mail completo sem modificações (por exemplo, ).

2. Verificar como o usuário do banco de dados foi criado

Você registrou o usuário pelo gcloud alloydb users create --type=IAM_BASED (ou pelo console/Terraform)? Criar um usuário com SQL bruto CREATE USER não vai funcionar para a autenticação do IAM porque o AlloyDB restringe GRANT alloydbiamuser ao plano de controle.

3. Verificar sua identidade ativa do ADC

Verifique se o ambiente em que o processo Java está sendo executado está autenticado como o principal do IAM de destino:

  • Estação de trabalho local (conectando-se como uma conta de serviço): execute gcloud auth application-default login --impersonate-service-account=java-alloydb-connector@.iam.gserviceaccount.com para que o ADC gere tokens para a conta de serviço em vez do seu e-mail pessoal.
  • Cloud Run / GKE: confirme se a conta de serviço está anexada à carga de trabalho e se tem roles/alloydb.client e roles/serviceusage.serviceUsageConsumer.

4. Considerar a propagação do IAM e o roteamento de rede

  • Atraso na propagação do IAM: as vinculações de políticas do IAM podem levar de 60 a 120 segundos para serem propagadas. Se você acabou de criar a conta de serviço ou a vinculação de papel, aguarde um minuto e tente de novo.
  • Acesso à rede VPC: por padrão, o conector Java do AlloyDB se conecta ao IP PRIVATE da instância. Se o aplicativo for executado no Cloud Run, configure a saída VPC direta (recomendada para menor latência e custo em relação aos conectores de acesso VPC sem servidor legados) ou conecte-se pelo Private Service Connect (PSC). Se estiver se conectando de uma máquina local fora da VPC, ative o IP público na instância e transmita alloydbIpType=PUBLIC.

7. Limpar

Para evitar cobranças desnecessárias na sua conta do Google Cloud e remover as identidades do IAM criadas durante este codelab, limpe os recursos abaixo.

1. Remover o usuário do banco de dados do IAM do AlloyDB e a conta de serviço

Exclua o usuário do banco de dados do IAM do cluster do AlloyDB e remova a conta de serviço:

# 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. Redefinir o Application Default Credentials local

Se você configurou a identidade temporária do ADC local, redefina as credenciais locais para a identidade de usuário padrão:

gcloud auth application-default login

3. (Opcional) Excluir o cluster do AlloyDB

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

8. Parabéns

Você concluiu o codelab e estabeleceu uma conectividade segura e sem senha do Java com o AlloyDB para PostgreSQL.

O que você realizou

  1. Configurou a autenticação de banco de dados do IAM: criou uma conta de serviço com privilégio mínimo, ativou alloydb.iam_authentication=on, registrou o usuário do IAM no cluster do AlloyDB e concedeu privilégios de tabela do PostgreSQL.
  2. Conectado com JDBC simples e HikariCP: configurou o HikariConfig com o com.google.cloud.alloydb.SocketFactory para criptografia mTLS 1.3 automática, atualização de token do IAM e resolução de IP dinâmico.
  3. Frameworks nativos da nuvem integrados: Spring Boot, Quarkus (Agroal) e Micronaut (HikariCP) configurados sem código boilerplate de pool de conexões personalizado, além de dicas de reflexão para GraalVM Native Image.
  4. Solução de problemas do IAM: aprendi a diagnosticar problemas de formatação de nome de usuário, personificação do ADC e roteamento de VPC.

Saiba mais