Integrando Spring Boot y Cloud SQL

Integrando Spring Boot y Cloud SQL

Este es el primer articulo de la serie Microservicios con Spring Boot y Google Cloud Platform (GCP), en donde vamos estar construyendo varios microservicios con Spring Boot e integrandolos con algunos servicios que ofrece GCP (Google Cloud Platform), para sacarle el maximo provecho a tus proyectos.

Entre los servicios con los que vamos a estar interactuando podemos encontrar:

Mas adelante, explicare que ofrece cada servicio y como los vamos a estar utilizando, sin embargo, lo primero que debemos hacer es crear nuestro proyecto base.

Nuestros microservicios

A lo largo de esta serie vamos a estar utlizando los recursos proporcionados en el siguiente repositorio de GitHub: https://github.com/jesushenriquez/gcp-microservices-spring-boot.

Para este articulo en particular vamos a utilizar el siguiente componente: https://github.com/jesushenriquez/gcp-microservices-spring-boot/tree/main/gcp-demo-services.

Conectandonos a GCP con el CLI

GCP ofrece un CLI por donde vas a poder interactuar con casi todos los servicios de tu consola.

  1. Primero que todo tienes que instalar el CLI, te puedes guiar desde la pagina principal.

  2. Luego, es necesario que nos autentiquemos para poder conectarnos a nuestra cuenta de google y nuestra consola, para esto lo puedes hacer con el siguiente comando:

gcloud auth login

Esto va a abrir un browser donde vas a poder autenticarte con tu cuenta de google.

Tambien puedes hacer la autenticación por medio de un Service Account, sin embargo, se sabe que los service account pueden ser un riesgo de seguridad si no se administran adecuadamente. Puedes ver otros metodos de autenticación en la pagina oficial de gcp.

Para verificar que ya estes autenticado, puedes ejecutar el siguiente comando:

gcloud auth list

Vas a poder visualizar tu correo electronico o service account en el output.

Creando nuestro proyecto

Dentro de GCP necesitamos crear o posicionarnos dentro de un proyecto, esto lo podemos hacer desde la consola web o desde el CLI, en nuestro casolo vamos a hacer desde el CLI:

gcloud projects create gcp-demo-jesushenriquez --name="GCP DEMO"

Luego vamos a setear dicho proyecto como proyecto por defecto:

gcloud config set project gcp-demo-jesushenriquez

Y puedes validar que efectivamente se configuro el default project ejecutando el siguiente comando:

gcloud config list project

Output:

Creando una instancia de Cloud SQL

Cloud SQL es un servicio de bases de datos completamente administrado que te ayuda a configurar, mantener y administrar tus bases de datos relacionales en Google Cloud Platform. Puedes usar Cloud SQL con MySQL, PostgreSQL o SQL Server.

Ahora, vamos a crear nuestra instancia de Cloud SQL, luego crearemos nuestra base de datos y posteriormente nuestras tablas.

  1. Lo primero que debemos hacer es habilitar las apis de administracion de Cloud SQL:
gcloud services enable sqladmin.googleapis.com

Output:

  1. Validamos que efectivamente habilitamos el api:
gcloud services list | grep sqladmin

Output:

  1. Validamos que no tengamos instancias creadas (por ahora) en nuestra consola y proyecto:
gcloud sql instances list

Output:

  1. Ahora si, vamos a crear nuestra instancia, vamos a ejecutar el siguiente comando donde especificamos el nombre de la instancia gcp-demo-sql y le pasamos el flag --region=us-central1 :
gcloud sql instances create gcp-demo-sql --region=us-central1

Veremos que por defecto Cloud SQL nos va a crear una instancia MySQL en mi caso v8.0, luego de unos minutos finalizara la creación de la instancia y visualizaras toda la información de la instancia creada:

De hecho, podrias validarlo desde la consola web y de igual forma visualizarias toda la información de tu instancia:

  1. Como ya tenemos nuestra instancia, podemos empezar a operar dentro de ella, en este caso vamos a crear nuestra base de datos:

Con el siguiente comando podemos visualizar que crearemos una base de datos llamada gcp-demo y le enviamos el flag --instance para indicarle el nombre de nuestra instancia gcp-demo-sql:

gcloud sql databases create gcp-demo --instance gcp-demo-sql

Luego de unos segundos, podrás visualizar un output con la información de tu base de datos:

  1. Vamos a crear el usuario mediante el cual nos conectaremos desde nuestro microservicio. En el siguiente comando podemos visualizar que vamos a crear el usuario guest en la instancia gcp-demo-sql y para efectos practivos vamos a asignarle el password guest.
gcloud sql users create guest --instance=gcp-demo-sql --host=% --password=guest
  1. Luego de crear nuestra base de datos y nuestro usuario, vamos a conectarnos a nuestra instancia a través del CLI y vamos a crear nuestras tablas (esto puede tardar unos minutos) , posteriormente tambien le daremos permisos al usuario guest.
gcloud sql connect gcp-demo-sql

Te va a pedir el password del usuario root, por defecto e inicialmente el password es vacio, es decir, con que presiones enter bastaria para conectarte.

En este punto, ya podemos interactuar con nuestra instancia mysql, de hecho, podriamos listar las bases de datos que tenemos a disposición y visualizaremos nuestra base de datos gcp-demo:

show databases;

Vamos a usar nuestra base de datos:

use gcp-demo;

Procedemos a crear nuestra tabla user :

CREATE TABLE user (
  id BIGINT NOT NULL AUTO_INCREMENT,
  name CHAR(255) NOT NULL,
  PRIMARY KEY (id)
);

Insertamos un usuario de prueba:

INSERT INTO user (id, name)
VALUES (1, 'Jesus');

Por ultimo, ejecutaremos el siguiente GRANT para darle todos los permisos sobre la base de datos al usuario guest:

GRANT ALL ON gcp-demo.* TO 'guest'@'%';

Y listo, salimos de la instancia:

exit

Integrando Cloud SQL en nuestro microservicio

Ya tenemos nuestra instancia de Cloud SQL con nuestra base de datos y nuestra tabla de usuarios, ahora vamos a integrarlo con nuestro microservicio.

En este punto es importante saber que existen varios metodos de conexión hacia Cloud SQL. En este articulo abordaremos Cloud SQL Starter.

Cloud SQL Starter

Cloud SQL Starter provee una autoconfiguración del object Datasource, y vamos a observar que no va a ser necesario definir propiedades como la url (jdbc path) que normalmente es necesario en un proyecto con spring data jpa.

  1. Lo primero que necesitamos hacer, es agregar una nueva dependency dentro de las dependencies de nuestro proyecto y dentro del dependencyManagement.
<dependencies>
    ...
    <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
    </dependency>
    ...
</dependencies>
...
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>spring-cloud-gcp-dependencies</artifactId>
            <version>2.0.4</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Importante: como nuestra instancia es MySQL vamos a utilizar el artifact spring-cloud-gcp-starter-sql-mysql, sin embargo, en dado caso que quieras conectarte a una instancia PostgreSQL puedes usar el artifact spring-cloud-gcp-starter-sql-postgresql. Lamentablemente, SQL Server no tiene compatibilidad con Cloud SQL Starter.

  1. Ahora vamos a necesitar obtener el connection name de nuestra instancia ejecutando el siguiente comando:
gcloud sql instances describe gcp-demo-sql --format='value(connectionName)'

  1. Luego, vamos a crear un archivo de propiedades con el profile cloud (application-cloud.yml). Dentro de nuestro archivo de propiedades vamos a escribir lo siguiente:
spring:
  cloud:
    gcp:
      sql:
        enabled: true
        database-name: <database_name>
        instance-connection-name: <instance_connection_name>
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 5
    username: <username>
    password: <password>
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect

Para mi caso en particular el archivo de propiedades se ve de la siguiente forma:

spring:
  cloud:
    gcp:
      sql:
        enabled: true
        database-name: gcp-demo
        instance-connection-name: gcp-demo-jesushenriquez:us-central1:gcp-demo-sql
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 5
    username: guest
    password: guest
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQLDialect
  1. Ahora es necesario agregar unas cuantes propiedades dentro de nuestro archivo de propiedades por default (application.yml):
server:
  port: 8080
spring:
  profiles:
    active: cloud

Basicamente, le estamos diciendo que el profile que esta activo es cloud. Esto ultimo le puedes dar el manejo que prefieras, es decir, puedes utilizar el application.yml o puedes enviar el profile al momento de ejecutar tu aplicación.

Toda esta información la puedes visualizar directamente en el proyecto https://github.com/jesushenriquez/gcp-microservices-spring-boot/tree/main/gcp-demo-services.

Creación de Service Acount

Llegamos a un punto importante de nuestra implementación, ya que para poder conectarnos a nuestra instancia de base de datos vamos a necesitar un service account con los permisos necesario hacia Cloud SQL.

  1. Para ello, lo primero que vamos hacer es crear nuestor service account.
gcloud iam service-accounts create guestgcpdemo

Aqui podemos ver que vamos a crear un service account con el account name guestgcpdemo.

  1. Procedemos a listar nuestros service accounts para obtener el email del sa que acabamos de crear:
gcloud iam service-accounts list

  1. Ahora, vamos a asignarle el role cloudsql.client, para que pueda conectarse a nuestra instancia.
gcloud projects add-iam-policy-binding gcp-demo-jesushenriquez --member serviceAccount:guestgcpdemo@gcp-demo-jesushenriquez.iam.gserviceaccount.com --role roles/cloudsql.client
  1. Necesitaremos exportar nuestro service account a un archivo JSON, el cual vamos a utilizar posteriormente.
gcloud iam service-accounts keys create guestgcpdemo.json --iam-account=guestgcpdemo@gcp-demo-jesushenriquez.iam.gserviceaccount.com

Este comando nos va a generar el archivo guestgcpdemo.json en la ruta donde estes ubicado.

  1. Por ultimo, vamos a configurar la variable de entorno GOOGLE_APPLICATION_CREDENTIALS el valor de esta variable debe ser la ruta completa de tu archivo JSON del service account: /path/guestgcpdemo.json.

De esta forma, utilizara el service account generado por defecto para cualquier operación con GCP que sea necesario. Tambien es posible enviarle la ruta directamente en el properties de nuestra aplicación.

Probando nuestro servicio

Para probar nuestra integración, vamos a utilizar el componente https://github.com/jesushenriquez/gcp-microservices-spring-boot/tree/main/gcp-demo-services que cuenta con un endpoint para obtener todos los usuarios de nuestra base de datos.

Ejecución

Para ejecutar nuestro microservicio es necesario tener instalado el JDK 17 y ejecutar el siguiente commando:

./mvnw spring-boot:run

image

Consumo de nuestro endpoint

Ya tenemos nuestro componente ejecutandose, ahora solo nos falta hacer la prueba. Para consumir nuestro endpoint lo puedes hacer utilizando el siguiente curl:

curl --location 'http://localhost:8080/users'

Podemos ver que nos muestra la información que tenemos en nuestra base de datos en Cloud SQL:

Importante: Eliminar la instancia de Cloud SQL

Si generaste una instancia para ir siguiendo los pasos de este articulo, recuerda eliminarla al finalizar la prueba, ya que si la dejas activa esto te generara un cobro a tu metodo de pago que tengas configurado en GCP.

Para eliminar la instancia puedes usar el siguiente comando:

gcloud sql instances delete gcp-demo-sql

Con esto finalizamos nuestra integración. Espero que este articulo te haya gustado y te ayude a entender un poco mejor como integrar tus aplicaciones en Spring Boot con Cloud SQL.

Si tienes alguna duda, puedes dejar un comentario en este articulo o tambien me puedes contactar en mastodon: https://mastodon.social/@jesushenriquez.