Gio Client
1. Descripción general
gio-client es una librería cliente (JAR) que actúa como fachada HTTP declarativa (@HttpExchange) sobre la API de GIO, según la description de su pom.xml: "Gio Client". GIO es la plataforma externa de gestión integral de ópticas que Hawkers utiliza para consultar fichas de pacientes/clientes (Gio.Paciente).
El proyecto no es un servicio desplegable ni contiene lógica de negocio propia: es una dependencia interna publicada en el registro de artefactos Maven de Hawkers, consumida por los microservicios del ecosistema que necesitan consultar datos de pacientes/clientes de óptica gestionados en GIO. Encapsula:
- Autenticación mediante JWT: obtención automática de un token de acceso vía
POST /api/v1/loginantes de cada petición, inyectado como headerAuthorization: Bearer {token}. - Un único endpoint de negocio expuesto: lectura de fichas de paciente (
Gio.Paciente/read), con soporte de filtros, ordenación y paginación. - Modelos de datos (DTO) para los payloads de petición/respuesta, con doble anotación Jackson/Gson.
Dentro del ecosistema de microservicios de Hawkers, gio-client cumple el mismo rol que otros clientes externos (eci-client, dynamics-client, falabella-client): aislar a los microservicios de negocio de los detalles de transporte HTTP, autenticación y serialización específicos de la API externa de GIO. Los datos manejados (nombre, documento de identidad, dirección, teléfono, email, fecha de nacimiento) tienen carácter de dato personal/sanitario, por lo que su tratamiento debe respetar las políticas de protección de datos aplicables (RGPD, campos rgpd_*/firmado_lopd presentes en los DTO).
2. Información técnica
| Propiedad | Valor |
|---|---|
artifactId | gio-client |
groupId | com.hawkersco |
version | 1.0.25-SNAPSHOT |
| Java | 25 |
| Spring Boot | 4.0.6 (spring-boot-starter-parent) |
| Tipo de artefacto | JAR (librería, no ejecutable) |
| Módulos | Proyecto único (no multi-módulo) |
3. Arquitectura y diseño
Estructura de paquetes bajo com.hawkersco.gioclient:
com.hawkersco.gioclient
├── GioClientApplication.java # @SpringBootApplication (arranque para pruebas locales)
├── client/
│ ├── GioTokenClient.java # @HttpExchange — POST /api/v1/login (obtención de JWT)
│ └── GioClient.java # @HttpExchange — POST /api/v1/core/Gio.Paciente/read
├── config/
│ ├── GioAuthProperties.java # @ConfigurationProperties("gio.auth.client") — record login/domain/username/password
│ └── GioClientConfig.java # @AutoConfiguration — beans GioTokenClient/GioClient + interceptor Bearer
└── pojo/
├── GetTokenRequest # payload de login (login_client, domain, username, password)
├── GioTokenResponse # respuesta de login (result, code, message, data.access_token)
├── GioReadRequest # payload de lectura (filter/order/pagination)
├── GioReadResponse # respuesta de lectura — ficha de paciente muy extensa (60+ campos)
├── CreateUpdateClienteRequest # DTO de alta/actualización de cliente (no referenciado por ningún método de GioClient)
└── UpdateClientGioNotification # DTO de notificación de actualización de cliente (no referenciado por ningún método de GioClient)
GioClientConfig se registra como auto-configuración Spring Boot en META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports, de modo que cualquier microservicio que añada gio-client como dependencia obtiene los beans GioTokenClient y GioClient automáticamente, condicionados (@ConditionalOnProperty) a que existan las propiedades gio.auth.client.url y gio.client.url. Las credenciales de login se inyectan vía el record @ConfigurationProperties GioAuthProperties (prefijo gio.auth.client), habilitado con @EnableConfigurationProperties.
Flujo principal de autenticación y llamada
sequenceDiagram
participant Consumidor as Microservicio consumidor
participant GioClient
participant Interceptor as RestClient Interceptor
participant GioTokenClient
participant GIO as API GIO
Consumidor->>GioClient: readPaciente(GioReadRequest)
GioClient->>Interceptor: intercepta petición saliente
Interceptor->>GioTokenClient: getToken(GetTokenRequest desde GioAuthProperties)
GioTokenClient->>GIO: POST /api/v1/login
GIO-->>GioTokenClient: JSON con data.access_token
Interceptor->>Interceptor: parsea respuesta con Gson (GsonBuilder ad-hoc)
Interceptor->>Interceptor: set header Authorization: Bearer {token}
Interceptor->>GIO: POST /api/v1/core/Gio.Paciente/read (con Bearer)
GIO-->>Consumidor: ResponseEntity<String> (JSON crudo)
Cabe destacar que, a diferencia de dynamics-client, la deserialización de la respuesta de login dentro del interceptor usa Gson (GsonBuilder instanciado ad-hoc en cada llamada), mientras el resto de anotaciones de los DTO soportan también Jackson.
4. Dependencias principales
| Dependencia | Propósito |
|---|---|
spring-boot-starter | Núcleo de Spring Boot y auto-configuración. |
spring-web | RestClient, HttpServiceProxyFactory y anotaciones @HttpExchange. |
org.projectlombok:lombok | Generación de getters/setters/constructores en los DTO. |
com.fasterxml.jackson.core:jackson-databind | Serialización/deserialización JSON principal (vía Spring RestClient). |
com.google.code.gson:gson | Deserialización puntual del token JWT dentro del interceptor de GioClientConfig. |
org.json:json | Presente en el classpath; sin uso localizado en las clases propias del proyecto (posible utilidad para el consumidor). |
com.google.cloud.artifactregistry:artifactregistry-maven-wagon (extensión de build) | Publicación del JAR en Google Artifact Registry (distributionManagement). |
No se listan dependencias de test más allá de spring-boot-starter-test (scope test), usada únicamente por el test de contexto GioClientApplicationTests.
5. API / Endpoints
No aplica como API REST propia. gio-client no expone endpoints; es una librería consumida como dependencia. GioClientApplication (@SpringBootApplication) existe únicamente como contexto de arranque para desarrollo/pruebas locales.
En su lugar, las interfaces GioTokenClient y GioClient declaran las operaciones disponibles contra la API externa de GIO:
| Método Java | HTTP | Ruta | Descripción |
|---|---|---|---|
GioTokenClient.getToken(GetTokenRequest) | POST | /api/v1/login | Obtiene un token JWT a partir de las credenciales configuradas. Uso interno del interceptor, no pensado para invocación directa del consumidor. |
GioClient.readPaciente(GioReadRequest) | POST | /api/v1/core/Gio.Paciente/read | Consulta fichas de paciente con filtros, orden y paginación. Devuelve JSON crudo (ResponseEntity<String>). |
Ejemplo de payload de petición (GioReadRequest):
{
"data": {
"filter": [
{ "field": "documento_identidad", "operator": "=", "value": "12345678A", "join": "AND" }
],
"order": [
{ "field": "fecha_creacion", "sort": "desc" }
],
"pagination": { "limit": 20, "page": 1 }
}
}
Ejemplo simplificado de estructura de respuesta (GioReadResponse):
{
"result": "OK",
"code": "200",
"message": "",
"data": {
"data": [
{
"id": 123,
"nombre_completo": "Ana García",
"documento_identidad": "12345678A",
"email": "ana@example.com",
"firmado_lopd": true,
"rgpd_firmada": true
}
],
"metadata": { "count": "1", "pagination": { "page": 1, "start": 0, "limit": 20 } }
}
}
6. Integraciones externas
| Sistema | Protocolo | Dirección | Detalle |
|---|---|---|---|
| API GIO — Login | HTTPS, JSON, POST /api/v1/login | Saliente | Obtención de token JWT usado para autenticar las peticiones de negocio. |
API GIO — Core (Gio.Paciente) | HTTPS, JSON, POST /api/v1/core/Gio.Paciente/read | Saliente | Consulta de fichas de paciente/cliente de la óptica. |
No hay otras integraciones (colas, SFTP, Dynamics 365, otros microservicios Hawkers, etc.) en este proyecto.
7. Configuración
src/main/resources/application.properties solo define spring.application.name=gio-client; el resto de propiedades deben ser aportadas por el microservicio consumidor:
| Clave | Descripción | Ejemplo de valor |
|---|---|---|
gio.auth.client.url | URL base del endpoint de login de GIO. | https://gio-api.hawkersco.net |
gio.client.url | URL base de la API principal de GIO (core). | https://gio-api.hawkersco.net |
gio.auth.client.login | Valor de login_client enviado en el payload de login. | ${GIO_LOGIN} |
gio.auth.client.domain | Dominio de la cuenta GIO. | ${GIO_DOMAIN} |
gio.auth.client.username | Usuario de la cuenta GIO. | ${GIO_USERNAME} |
gio.auth.client.password | Contraseña de la cuenta GIO. | ******** |
Si faltan gio.auth.client.url o gio.client.url, los beans GioTokenClient/GioClient no se registran (@ConditionalOnProperty), sin error de arranque explícito.
8. Persistencia
No aplica. El proyecto no gestiona base de datos ni realiza persistencia propia; todos los DTO son objetos de transporte para las llamadas HTTP a la API de GIO.
9. Procesos programados y mensajería
No aplica. No existen @Scheduled, @KafkaListener ni @RabbitListener en el código. La ejecución de la consulta de pacientes es responsabilidad del microservicio consumidor, que decide cuándo invocarla.
10. Ejecución en local
Requisitos previos:
- JDK 25.
- Maven Wrapper (
./mvnw, incluido en el repositorio). - Credenciales válidas de GIO (proporcionadas por el consumidor vía las propiedades de la sección 7).
Comandos:
# Build sin tests (equivalente al comportamiento de CI)
./mvnw clean install -DskipTests
# Build con tests
./mvnw clean install
# Ejecutar tests
./mvnw test
# Ejecutar una clase de test concreta
./mvnw test -Dtest=GioClientApplicationTests
# Ejecutar un método de test concreto
./mvnw test -Dtest=GioClientApplicationTests#contextLoads
Al ser una librería, no se "levanta" como servicio independiente ni expone actuator/health. El único test existente (GioClientApplicationTests#contextLoads) verifica que el contexto de Spring arranca correctamente. Para probarla en local es necesario:
- Instalarla en el repositorio Maven local (
./mvnw clean install) o consumir la versión publicada en Artifact Registry. - Añadirla como dependencia en un microservicio consumidor que defina las propiedades
gio.*de la sección 7. - Verificar el correcto arranque comprobando que los beans
GioTokenClient/GioClientse inyectan sin error en el microservicio consumidor.
11. Despliegue
El proyecto se publica como artefacto Maven en Google Artifact Registry (artifactregistry://europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven), no se despliega como contenedor ni servicio.
El Jenkinsfile define un pipeline de dos etapas:
- Checkout —
checkout scm. - Publish to Artifact Registry —
mvn deploy -DskipTests.
Job de Jenkins del proyecto: https://jenkins-pi.hawkersco.net/job/gio-client/
12. Manejo de errores y logging
- Los métodos
GioClient.readPacienteyGioTokenClient.getTokendeclaranthrows RestClientResponseException, dejando que los errores HTTP de la API de GIO (4xx/5xx) se propaguen directamente al consumidor sin envoltura adicional. - El interceptor de
GioClientConfigno captura excepciones al obtener/parsear el token: si la llamada de login falla o el cuerpo de la respuesta no es el JSON esperado, la excepción de Gson (JsonSyntaxException) o la deRestClientResponseExceptionse propaga sin control, abortando la petición de negocio. - No hay un
@ControllerAdviceni códigos de error propios, al no exponer API REST propia. - No hay configuración de logging específica en el proyecto; hereda la configuración de logs del consumidor.
13. Notas y consideraciones
- A diferencia de
dynamics-client(que también obtiene un token en cada petición), aquí el interceptor no cachea el token JWT: se solicita un nuevo login en cada llamada areadPaciente, lo que implica una petición HTTP adicional por cada consulta de paciente y mayor latencia/carga sobre el endpoint de login de GIO. - Los DTO
CreateUpdateClienteRequestyUpdateClientGioNotificationexisten en el paquetepojopero no están referenciados por ningún método deGioClientniGioTokenClienten este repositorio; parecen preparados para funcionalidades futuras (alta/actualización de cliente) aún no implementadas en la interfaz de cliente. Pendiente de verificar si se usan directamente desde algún consumidor. GioReadResponsemodela una ficha de paciente muy extensa (60+ campos: identificación, contacto, campos RGPD/LOPD, información fiscal, discapacidad, RIPS...), reflejando la naturaleza sensible de los datos gestionados por GIO. Cualquier microservicio consumidor debe tratar estos datos conforme a la normativa de protección de datos aplicable.- La dependencia
org.json:jsonestá declarada en elpom.xmlpero no se ha localizado ningún uso en las clases propias del proyecto; podría estar pensada para uso del consumidor o ser una dependencia residual. Pendiente de verificar. - Las clases internas no estáticas
GioReadResponse.Data,GioReadResponse.Data.Datum,GioReadResponse.Data.Metadata,GioReadResponse.Data.PaginationyGioTokenResponse.Dataestán declaradas sin el modificadorstatic, a diferencia del resto de DTO anidados del proyecto (que sí sonstatic); esto es funcionalmente correcto para Jackson/Gson (ambos instancian sin depender de la instancia externa en deserialización estándar), pero es una inconsistencia de estilo respecto al resto de POJOs del ecosistema Hawkers. - No existen tests más allá del test de contexto (
contextLoads); no hay tests unitarios para el interceptor de autenticación ni para la lectura de pacientes.