Skip to main content

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/login antes de cada petición, inyectado como header Authorization: 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

PropiedadValor
artifactIdgio-client
groupIdcom.hawkersco
version1.0.25-SNAPSHOT
Java25
Spring Boot4.0.6 (spring-boot-starter-parent)
Tipo de artefactoJAR (librería, no ejecutable)
MódulosProyecto ú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

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot y auto-configuración.
spring-webRestClient, HttpServiceProxyFactory y anotaciones @HttpExchange.
org.projectlombok:lombokGeneración de getters/setters/constructores en los DTO.
com.fasterxml.jackson.core:jackson-databindSerialización/deserialización JSON principal (vía Spring RestClient).
com.google.code.gson:gsonDeserialización puntual del token JWT dentro del interceptor de GioClientConfig.
org.json:jsonPresente 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 JavaHTTPRutaDescripción
GioTokenClient.getToken(GetTokenRequest)POST/api/v1/loginObtiene 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/readConsulta 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

SistemaProtocoloDirecciónDetalle
API GIO — LoginHTTPS, JSON, POST /api/v1/loginSalienteObtención de token JWT usado para autenticar las peticiones de negocio.
API GIO — Core (Gio.Paciente)HTTPS, JSON, POST /api/v1/core/Gio.Paciente/readSalienteConsulta 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:

ClaveDescripciónEjemplo de valor
gio.auth.client.urlURL base del endpoint de login de GIO.https://gio-api.hawkersco.net
gio.client.urlURL base de la API principal de GIO (core).https://gio-api.hawkersco.net
gio.auth.client.loginValor de login_client enviado en el payload de login.${GIO_LOGIN}
gio.auth.client.domainDominio de la cuenta GIO.${GIO_DOMAIN}
gio.auth.client.usernameUsuario de la cuenta GIO.${GIO_USERNAME}
gio.auth.client.passwordContraseñ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:

  1. Instalarla en el repositorio Maven local (./mvnw clean install) o consumir la versión publicada en Artifact Registry.
  2. Añadirla como dependencia en un microservicio consumidor que defina las propiedades gio.* de la sección 7.
  3. Verificar el correcto arranque comprobando que los beans GioTokenClient/GioClient se 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:

  1. Checkoutcheckout scm.
  2. Publish to Artifact Registrymvn 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.readPaciente y GioTokenClient.getToken declaran throws RestClientResponseException, dejando que los errores HTTP de la API de GIO (4xx/5xx) se propaguen directamente al consumidor sin envoltura adicional.
  • El interceptor de GioClientConfig no 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 de RestClientResponseException se propaga sin control, abortando la petición de negocio.
  • No hay un @ControllerAdvice ni 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 a readPaciente, 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 CreateUpdateClienteRequest y UpdateClientGioNotification existen en el paquete pojo pero no están referenciados por ningún método de GioClient ni GioTokenClient en 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.
  • GioReadResponse modela 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:json está declarada en el pom.xml pero 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.Pagination y GioTokenResponse.Data están declaradas sin el modificador static, a diferencia del resto de DTO anidados del proyecto (que sí son static); 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.