Conectar usando o PGAdapter

Este documento descreve como se conectar ao Spanner Omni usando o PGAdapter. Você configura o PGAdapter para estabelecer conexões seguras. O PGAdapter oferece suporte a conexões de texto simples, Transport Layer Security (TLS), TLS com credenciais, e TLS mútuo (mTLS). Essas configurações de segurança protegem seus dados durante a transmissão, fornecendo níveis variados de criptografia e autenticação. Cada configuração exige configurações específicas do cliente para garantir a integridade de dados e a confidencialidade.

É possível executar o PGAdapter como um processo independente ou integrá-lo diretamente ao aplicativo. Para gerenciamento interativo e execução manual de consultas, conecte-se ao banco de dados usando ferramentas padrão do PostgreSQL, como psql. Para criar aplicativos automatizados, use drivers compatíveis com o PostgreSQL, como:

Para exemplos de código que usam alguns desses drivers, consulte exemplo de código em este documento.

Antes de começar

Para usar o PGAdapter com o Spanner Omni, use a versão 0.55.2 ou mais recente do PGAdapter.

Se você usar o Maven sem a lista de materiais (BOM), adicione o seguinte às dependências do arquivo pom.xml:

<dependency>
  <groupId>com.google.cloud</groupId>
  <artifactId>google-cloud-spanner-pgadapter</artifactId>
  <version>0.55.2</version>
</dependency>

Configurações de segurança

O PGAdapter do Spanner Omni oferece suporte a quatro configurações de segurança, que definem como a comunicação é criptografada e autenticada entre o PGAdapter e o banco de dados. Para usar essas configurações, defina as opções do cliente descritas na tabela a seguir:

Configuração de segurança Descrição
Texto simples A comunicação não é criptografada.
TLS A comunicação é criptografada usando o Transport Layer Security (TLS). Essa configuração exige que você adicione o certificado de CA do Spanner Omni ao truststore Java, conforme descrito em Configurar o truststore Java.
TLS com credenciais A comunicação é criptografada usando TLS, e a autenticação é realizada usando um nome de usuário e uma senha.
mTLS A comunicação é criptografada usando TLS mútuo (mTLS). Essa configuração exige que você forneça um certificado e uma chave privada do cliente.

Executar como um processo independente

Execute o PGAdapter como um processo independente para aplicativos não Java e para ferramentas padrão do PostgreSQL, por exemplo, psql, quando precisar de interação manual com o banco de dados. Essa abordagem desvincula o proxy do ciclo de vida do aplicativo, o que permite gerenciá-lo e atualizá-lo de forma independente. Para iniciar o PGAdapter como um processo independente, use os seguintes métodos de configuração com base na configuração de segurança selecionada:

Texto simples

Para iniciar o PGAdapter com comunicação de texto simples, execute o seguinte comando:

java -jar pgadapter.jar \
     -d DATABASE_ID \
     -e ENDPOINT \
     -r "type=omni;usePlainText=true"

Substitua:

  • DATABASE_ID: o ID do banco de dados do Spanner Omni, por exemplo, test-db.

  • ENDPOINT: o endpoint da instância do Spanner Omni, por exemplo, localhost:15000.

TLS

Para configurar uma conexão do PGAdapter usando TLS, adicione o certificado de CA do Spanner Omni ao truststore Java, conforme descrito em Configurar o truststore Java.

Para iniciar o PGAdapter usando TLS, execute o seguinte comando:

java -Djavax.net.ssl.trustStore=$JAVA_HOME/lib/security/cacerts \
     -Djavax.net.ssl.trustStoreType=JKS \
     -jar pgadapter.jar \
     -d DATABASE_ID \
     -e ENDPOINT \
     -r "type=omni"

TLS com credenciais

Para estabelecer uma conexão TLS com autenticação de nome de usuário e senha, use o parâmetro -r para especificar o username e a password:

java -Djavax.net.ssl.trustStore=$JAVA_HOME/lib/security/cacerts \
     -Djavax.net.ssl.trustStoreType=JKS \
     -jar pgadapter.jar \
     -d DATABASE_ID \
     -e ENDPOINT \
     -r "type=omni;username=USERNAME;password=PASSWORD"

Substitua:

  • USERNAME: o nome de usuário do usuário do Spanner Omni.

  • PASSWORD: a senha do usuário do Spanner Omni.

mTLS

Antes de iniciar o PGAdapter usando mTLS, verifique se a chave do cliente está no formato PKCS#8. Para converter uma chave atual no formato PKCS#8, execute o seguinte comando:

openssl pkcs8 -topk8 -in ~/.spanner/certs/client.key -out ~/.spanner/certs/java-client.key -nocrypt

Como alternativa, ao criar o certificado e a chave do cliente usando a CLI do Spanner Omni, forneça o parâmetro --generate-pkcs8-key para gerar a chave no formato PKCS#8.

Para iniciar o PGAdapter usando mTLS, execute o seguinte comando:

java -Djavax.net.ssl.trustStore=$JAVA_HOME/lib/security/cacerts \
    -Djavax.net.ssl.trustStoreType=JKS \
    -jar pgadapter.jar \
    -d DATABASE_ID \
    -e ENDPOINT \
    -r "type=omni;clientCertificate=PATH_TO_CLIENT_CERT;clientKey=PATH_TO_CLIENT_KEY"

Substitua:

  • PATH_TO_CLIENT_CERT: o caminho para o arquivo de certificado do cliente.

  • PATH_TO_CLIENT_KEY: o caminho para o arquivo de chave do cliente.

Conectar-se ao psql

Depois de estabelecer uma conexão usando um dos métodos anteriores, execute psql para gerenciar o banco de dados e executar consultas. Para se conectar ao psql, use o seguinte comando:

psql -h PG_HOST -p PG_PORT -U USERNAME -d DATABASE_ID

Substitua:

  • PG_HOST: o nome do host ou o endereço IP da máquina em que o PGAdapter está em execução. Se estiver executando localmente, use localhost.

  • PG_PORT: o número da porta em que o PGAdapter está em execução. Se você não tiver especificado uma porta personalizada, o PGAdapter usará a porta 5432 por padrão.

  • USERNAME: seu nome de usuário do PostgreSQL.

Executar no processo com seu aplicativo

Também é possível iniciar o PGAdapter no processo com seu aplicativo. Para estabelecer a segurança, configure o objeto OptionsMetadata para cada configuração de segurança compatível:

Texto simples

Para comunicação de texto simples em ambientes como desenvolvimento ou teste local, use a seguinte configuração:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
        .setEndpoint("ENDPOINT")
        .setType("omni")
        .setUsePlainText();

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

TLS

Para estabelecer uma conexão TLS, adicione o certificado de CA ao truststore Java , conforme descrito em Configurar o truststore Java, e use a seguinte configuração:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
        .setEndpoint("ENDPOINT")
        .setType("omni");

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

TLS com credenciais

Para estabelecer uma conexão TLS com autenticação de nome de usuário e senha, use setProperties() para especificar o nome de usuário e a senha:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
        .setEndpoint("ENDPOINT")
        .setType("omni")
        .setProperties(
            Map.of(
                "username", "USERNAME",
                "password", "PASSWORD"));

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

mTLS

Para iniciar o PGAdapter no processo com seu aplicativo Java usando mTLS, a chave do cliente precisa usar o formato PKCS#8.

Para estabelecer uma conexão mTLS no processo, use esta configuração:

OptionsMetadata.Builder builder =
    OptionsMetadata.newBuilder()
        .setEndpoint("ENDPOINT")
        .setType("omni")
        .useClientCert(
            "PATH_TO_CLIENT_CERT",
            "PATH_TO_CLIENT_KEY");

ProxyServer server = new ProxyServer(builder.build());
server.startServer();
server.awaitRunning();

Exemplo de código

Esta seção fornece um exemplo de código para se conectar a um banco de dados do Spanner Omni usando os seguintes drivers compatíveis com o PostgreSQL:

Substitua o seguinte marcador de posição nas strings de conexão:

  • PASSWORD: a senha do usuário do PostgreSQL.

JDBC

É possível se conectar ao PGAdapter usando o driver JDBC do PostgreSQL como se estivesse se conectando a um banco de dados do PostgreSQL. Para se conectar e consultar uma tabela em um banco de dados do Spanner Omni, use o seguinte exemplo de código:

String jdbcUrl =
    "jdbc:postgresql://PG_HOST:PG_PORT/DATABASE_ID";

try (Connection connection = DriverManager.getConnection(jdbcUrl)) {
  // Example: Query data
  try (Statement statement = connection.createStatement();
      ResultSet resultSet = statement.executeQuery("SELECT * FROM Singers")) {

    System.out.println("Query Results:");
    while (resultSet.next()) {
      long id = resultSet.getLong("id");
      String name = resultSet.getString("name");
      System.out.printf("ID: %d, Name: %s\n", id, name);
    }
  } catch (SQLException e) {
    throw new RuntimeException(e);
  }
}

Go (pgx)

É possível se conectar ao PGAdapter usando pgx como se estivesse se conectando a um banco de dados do PostgreSQL. Use o seguinte exemplo de código:

// Database connection string
connString := "postgres://USERNAME:PASSWORD@PG_HOST:PG_PORT/DATABASE_ID?sslmode=disable"
ctx := context.Background()

// Connect to PGAdapter
conn, err := pgx.Connect(ctx, connString)
if err != nil {
  log.Fatalf("Connection error: %s", err.Error())
}
defer conn.Close(ctx)

// Query all rows from the Singers table
rows, err := conn.Query(ctx, "SELECT id, name FROM Singers")
if err != nil {
  log.Fatalf("Query error: %s", err.Error())
}
defer rows.Close()

// Iterate over the result set
fmt.Println("Singers Table Data:")
for rows.Next() {
  var id int
  var name string
  if err := rows.Scan(&id, &name); err != nil {
    log.Fatalf("Scan error: %s", err.Error())
  }
  fmt.Printf("ID: %d, Name: %s\n", id, name)
}

Python (psycopg2 ou psycopg3)

É possível se conectar ao PGAdapter usando psycopg2 ou psycopg3 como se estivesse se conectando a um banco de dados do PostgreSQL. Para se conectar e consultar uma tabela em um banco de dados do Spanner Omni, use o seguinte exemplo de código:

# psycopg2
import psycopg2

connection = psycopg2.connect(database="DATABASE_ID",
                              host="PG_HOST",
                              port=PG_PORT)

cursor = connection.cursor()
cursor.execute('SELECT * FROM Singers')
for row in cursor:
  print(row)

cursor.close()
connection.close()


# psycopg3
import psycopg

with psycopg.connect("host=PG_HOST port=PG_PORT dbname=DATABASE_ID sslmode=disable") as conn:
  conn.autocommit = True
  with conn.cursor() as cur:
    cur.execute("SELECT * FROM Singers")
    for row in cur:
      print(row)

Node.js (node-postgres)

É possível se conectar ao PGAdapter usando node-postgres como se estivesse se conectando a um banco de dados do PostgreSQL. Para se conectar e consultar uma tabela em um banco de dados do Spanner Omni, use o seguinte exemplo de código:

const { Client } = require('pg');
const client = new Client({
  host: 'PG_HOST',
  port: PG_PORT,
  database: 'DATABASE_ID',
});
await client.connect();
const res = await client.query("SELECT * FROM Singers");
console.log(res.rows);
await client.end();