Skip to main content

orders-to-bi

1. Descripción general

Según el pom.xml, el proyecto se describe como "Send orders and refunds to BI". Es un servicio ligero de Spring Boot, sin servidor web ni base de datos, que mediante tareas programadas (@Scheduled) descarga ficheros XML de pedidos, devoluciones, clientes e inventario desde servidores SFTP (Hawkers producción/staging, proveedor GFK) y los sube al datalake de BI en Google Cloud Storage.

Nótese que tanto el groupId (com.hawkerco) como el paquete Java raíz (com.hawkerco.orderstobi) tienen una errata (falta la "s" de "hawkersco"), consistente en todo el proyecto.

2. Información técnica

CampoValor
artifactIdorders-to-bi
groupIdcom.hawkerco (nótese la errata, sin la "s" de "hawkersco")
version1.0.25
Java25
Spring Boot4.0.6
Tipo de artefactojar (ejecutable, servicio de larga duración con tareas programadas)
MódulosNo aplica (proyecto de módulo único)

3. Arquitectura y diseño

No es una API REST ni un CommandLineRunner: es un servicio de larga duración con 5 tareas @Scheduled activas y 2 deshabilitadas, todas en component/OrdersToBiSchedule.

TareaProgramaciónOrigen → Destino
ordersToBiProductionCada 5 minSFTP producción Hawkers → GCS (pedidos XML)
refundsToBiProductionCada 5 minSFTP producción Hawkers → GCS (devoluciones XML)
customersToBiProductionCada 5 minSFTP producción Hawkers → GCS (clientes XML)
cleanInventoryFilesDiaria a medianocheBorra ficheros de inventario ya procesados en SFTP producción
microStrategyMoveFileLunes 10:50 (Europe/Madrid)SFTP staging → renombra y sube CSV a SFTP del proveedor GFK
ordersToBiStagingDeshabilitada (@Scheduled comentado)SFTP staging → GCS (pedidos XML)
refundsToBiStagingDeshabilitada (@Scheduled comentado)SFTP staging → GCS (devoluciones XML)
  • .utilsOrdersToBiUtils (filtrado por regex, extracción de prefijo de sitio del nombre de fichero, lógica de transferencia SFTP→GCS).
flowchart TD
A["@Scheduled cada 5 min"] -->|descarga XML| B[SFTP producción Hawkers]
A -->|filtra por regex, extrae prefijo de sitio| C[OrdersToBiUtils]
C -->|sube| D["GCS ingestion/sfcc/{site}/{type}/output/timestamp={fecha}/"]
A -->|"@Scheduled lunes 10:50"| E[SFTP staging]
E -->|renombra CSV| F[SFTP GFK]

4. Dependencias principales

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot (@Scheduled)
com.hawkersco:pi-function-commonsSftpUtils, StorageUtils, DateUtils, DirectoryUtils
com.hawkersco:sfcc-commonsModelos compartidos

5. API / Endpoints

No aplica a este proyecto. No expone capa REST; opera exclusivamente mediante tareas programadas.

6. Integraciones externas

SistemaProtocoloDirecciónDetalle
Servidor SFTP sftp.hawkersco.com (producción y staging, usuarios distintos)SFTPEntranteDescarga de XML de pedidos/devoluciones/clientes/inventario
Servidor SFTP GFK (gimftp.gfk.com)SFTPSalienteSubida del fichero CSV semanal para MicroStrategy
Google Cloud Storage (proyecto bi-saldum)API de GCS, autenticación por clave de cuenta de servicioSalienteIngesta de ficheros al datalake de BI

7. Configuración

En producción, las credenciales SFTP llegan por variables de entorno inyectadas como Secret de Kubernetes; en local (application.properties) el repositorio contiene actualmente valores reales hardcodeados (ver alerta de seguridad crítica).

ClaveDescripción
gcs.bucket.name / .name.proBuckets de destino en GCS (dev/producción)
orderstobi.ftp.staging.* / .production.*Credenciales SFTP de Hawkers (staging y producción)
gfk.ftp.*Credenciales SFTP del proveedor GFK
orderstobi.ftp.regex.*Patrones de nombre de fichero por tipo (pedidos, devoluciones, inventario, clientes)

🛑 Alerta de seguridad crítica — clave privada de cuenta de servicio de GCP comprometida en el repositorio

El fichero certificates/bi-saldum-519f49efa11b.json, presente físicamente en este repositorio (no en .gitignore como afirma el CLAUDE.md existente: "GCP auth: certificates/bi-saldum-519f49efa11b.json (service account key, not committed)"), es una clave privada completa de una cuenta de servicio de Google Cloud (type: service_account, proyecto bi-saldum, cuenta pi-kafka-gcs@bi-saldum.iam.gserviceaccount.com). El propio pom.xml la incluye explícitamente en el plugin Jib (extraDirectories, copiando certificates/ a /certificates dentro de la imagen Docker) para que la aplicación la use en tiempo de ejecución (OrdersToBiSchedule.initStorage() la carga directamente desde disco).

Esto es una clave criptográfica real, no una simple contraseña: cualquiera con acceso a este repositorio (incluyendo su historial de control de versiones) puede autenticarse como esa cuenta de servicio y actuar con los permisos de GCP que tenga asignados en el proyecto bi-saldum (previsiblemente, al menos, escritura en el datalake de BI). No se ha reproducido ningún fragmento de la clave privada en este documento.

Se recomienda con prioridad máxima:

  1. Revocar/rotar inmediatamente la clave de la cuenta de servicio pi-kafka-gcs@bi-saldum.iam.gserviceaccount.com desde la consola de IAM de GCP (proyecto bi-saldum), generando una nueva clave.
  2. Eliminar el fichero certificates/bi-saldum-519f49efa11b.json del repositorio y de su historial de Git.
  3. Sustituir la autenticación por fichero de clave por un mecanismo gestionado (Workload Identity en GKE, o montaje de la clave como Secret de Kubernetes en tiempo de despliegue, nunca versionado en el repositorio de código).
  4. Auditar los logs de acceso de esa cuenta de servicio en GCP para descartar uso no autorizado, dado que la fecha del fichero (2020, según metadatos) sugiere una exposición prolongada.

Además, application.properties contiene las contraseñas SFTP reales de Hawkers (staging y producción) y del proveedor GFK, no reproducidas en este documento. Se recomienda rotarlas también.

8. Persistencia

No aplica a este proyecto. No usa base de datos: el estado se traspasa íntegramente vía ficheros en SFTP/GCS.

9. Procesos programados y mensajería

Descritos en su totalidad en la tabla de la sección 3; no hay CommandLineRunner ni CronJob de Kubernetes — el servicio se despliega como Deployment de una réplica, de larga duración, con las tareas programadas gestionadas internamente por Spring (@Scheduled).

10. Ejecución en local

Requisitos previos: JDK 25, Maven, credenciales SFTP válidas y una clave de cuenta de servicio de GCP (idealmente no la comprometida del repositorio, ver alerta de seguridad).

# Compilar sin tests
./mvnw -B -DskipTests clean install

# Ejecutar tests
./mvnw test

# Build Docker
docker build -t orders-to-bi .

Al no ser una API REST, no hay endpoint de health check: la verificación se hace revisando el log de consola o los ficheros reflejados en GCS.

11. Despliegue

  • Imagen: construida con jib-maven-plugin (base eclipse-temurin:25-jre, containerizingMode=packaged, incluye el directorio certificates/ completo —con la clave de cuenta de servicio— dentro de la imagen), publicada en europe-west3-docker.pkg.dev/pi-saldum/pi-repo/orders-to-bi:<tag>.
  • Orquestación: Kubernetes Deployment (una réplica) en el clúster GKE pi-cluster-hw, namespace pi, contenedor no privilegiado.
  • CI/CD (Jenkins): pipeline real de 3 etapas — CheckoutBuild & PushDeploy to GKE.

Job de Jenkins: https://jenkins-pi.hawkersco.net/job/orders-to-bi/

12. Manejo de errores y logging

No hay una estrategia de excepciones centralizada. Cada tarea programada captura sus propias excepciones (IllegalAccessException, JSchException, IOException, SftpException, ParseException) y registra el mensaje sin propagar el error, de modo que un fallo en una ejecución no impide que la tarea vuelva a ejecutarse en el siguiente ciclo programado. Logging mediante java.util.logging.Logger estándar (consola).

13. Notas y consideraciones

🛑 Ver alerta de seguridad crítica en la sección 7

Es, con diferencia, el hallazgo más grave de todo este lote de documentación: una clave privada de cuenta de servicio de GCP comprometida y activamente empaquetada en la imagen de producción.

Otros hallazgos

  • Errata en groupId y paquete Java: com.hawkerco en lugar de com.hawkersco, consistente en todo el proyecto (Maven y paquete Java) — no afecta a la funcionalidad, pero es una inconsistencia notable frente al resto de proyectos de este ecosistema.
  • CLAUDE.md verificado y consistente en el resto de aspectos: las 5 tareas activas y las 2 deshabilitadas, sus horarios exactos, el patrón de convención de rutas en GCS, y el flujo GFK/MicroStrategy coinciden con el código real, verificado directamente en OrdersToBiSchedule — la única afirmación incorrecta es la relativa a que la clave de GCP "no está comprometida en el repositorio".