Integrando Spring Boot y Cloud SQL
En este articulo vamos a integrar Spring Boot con Cloud SQL de Google Cloud Platform (GCP), vamos a crear un servicio REST basico con Spring Boot y vamos a disponibilizar una base de datos a través de cloud sql utilizandola para persistir y leer información de usuarios.
Nuestros microservicios
A lo largo de este articulo vamos a estar utlizando los recursos proporcionados en el siguiente repositorio de GitHub: 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.
Primero que todo tienes que instalar el CLI, te puedes guiar desde la pagina principal.
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.
Lo primero que debemos hacer es habilitar las apis de administracion de Cloud SQL:
gcloud services enable sqladmin.googleapis.com
Output:
Validamos que efectivamente habilitamos el api:
gcloud services list | grep sqladmin
Output:
Validamos que no tengamos instancias creadas (por ahora) en nuestra consola y proyecto:
gcloud sql instances list
Output:
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:
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:
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 instanciagcp-demo-sql
y para efectos practivos vamos a asignarle el passwordguest
.
gcloud sql users create guest --instance=gcp-demo-sql --host=% --password=guest
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.
Lo primero que necesitamos hacer, es agregar una nueva
dependency
dentro de lasdependencies
de nuestro proyecto y dentro deldependencyManagement
.
<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.
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)'
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 properties 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
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.
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
.
Procedemos a listar nuestros service accounts para obtener el email del sa que acabamos de crear:
gcloud iam service-accounts list
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
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.
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
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.