recovery-logistic-status
1. Descripción general
Según el pom.xml, el proyecto se describe como "Recovery logistic status". Es un microservicio batch que recupera el estado de envío desde 6 carriers logísticos distintos (Auro, Auro/Cooper para lentes, LogSolution/Asendia, Sprint Logistics EU y GB, Cubbo) y lo sincroniza tanto en la base de datos de logística (ShipmentStatusHistory) como en Dynamics (OrderStatusPro). Sigue el mismo patrón de procesadores orquestados en paralelo ya visto en pickup-point-update-db.
2. Información técnica
| Campo | Valor |
|---|---|
artifactId | recovery-logistic-status |
groupId | com.hawkersco |
version | 1.0.25 |
| Java | 25 (maven.compiler.release=25) |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | jar (ejecutable, Spring Boot batch/CLI) |
| Módulos | No aplica (proyecto de módulo único) |
3. Arquitectura y diseño
No es una API REST: es una aplicación Spring Boot CLI con un patrón de procesadores intercambiables ejecutados en paralelo.
RecoveryLogisticStatusProcessor— interfaz común (process(),getName()).RecoveryLogisticStatusOrchestrator(ApplicationRunner) — descubre todos los procesadores registrados, filtra los activos según la propiedadrecovery.carriers(vacío = todos), y los ejecuta en paralelo con unExecutorServicedimensionado al número de procesadores activos.- 6 runners, cada uno implementando
RecoveryLogisticStatusProcessorpara un carrier:
Runner (getName()) | Carrier | Estados recuperados |
|---|---|---|
RecoveryLogisticStatusAuroRunner (auro) | Auro (España) | REPT, CONF |
RecoveryLogisticStatusAuroLensesRunner (auro-lenses) | Auro/Cooper (lentillas) | REPT, CONF |
RecoveryLogisticStatusLogsolutionRunner (logsolution) | LogSolution/Asendia (Italia, SOAP) | OUT_OF_DLV, DELIVERED |
RecoveryLogisticStatusSprintLogisticsRunner (sprint) | Sprint Logistics (UE) | DELIVERED |
RecoveryLogisticStatusSprintLogisticsGbRunner (sprint-gb) | Sprint Logistics (Reino Unido) | DELIVERED |
RecoveryLogisticStatusCubboRunner (cubbo) | Cubbo (México) | SHIPMENT_OUT_FOR_DELIVERY, SHIPMENT_DELIVERED |
.config—DynamicsDbConfig(datasource primariodynamics-pro),LogisticsDbConfig(datasource secundariologistics),RecoveryLogisticStatusConfig..util—RecoveryLogisticStatusUtil(construcción de payloads, guardado de historial de estado y estado de pedido, compartido por los runners que lo necesitan).
flowchart TD
A[RecoveryLogisticStatusOrchestrator] -->|filtra por recovery.carriers| B{Procesadores activos}
B -->|en paralelo| C[Auro]
B -->|en paralelo| D[Auro Lentes]
B -->|en paralelo| E[LogSolution]
B -->|en paralelo| F[Sprint EU]
B -->|en paralelo| G[Sprint GB]
B -->|en paralelo| H[Cubbo]
C -->|consulta pedidos sin estado final| I[(logistics · Order/Shipment)]
C -->|consulta API carrier| J[Auro API]
C -->|guarda| K[(logistics · ShipmentStatusHistory)]
C -->|guarda| L[(dynamics-pro · OrderStatusPro)]
Doble datasource
DynamicsDbConfig (primario, BD dynamics-pro, entidad principal OrderStatusPro) y LogisticsDbConfig (secundario, BD logistics, entidades Order, Shipment, ShipmentStatusHistory, Carrier). Pool HikariCP ampliado a mín. 3 / máx. 10 conexiones (frente al máximo 5 habitual en otros runners) para soportar los 6 procesadores concurrentes.
4. Dependencias principales
| Dependencia | Propósito |
|---|---|
spring-boot-starter | Núcleo de Spring Boot (sin web, es un runner CLI) |
com.hawkersco:logistics-commons | Entidades/servicios de la BD logistics |
com.hawkersco:dynamics-commons | Entidad/servicio OrderStatusPro de la BD dynamics-pro |
com.hawkersco:auro-client | Cliente para Auro (España y lentes) |
com.hawkersco:cubbo-client | Cliente para Cubbo |
com.hawkersco:logsolution-client | Cliente SOAP para LogSolution |
com.hawkersco:sprintlogistics-client | Cliente para Sprint Logistics (EU y GB, credenciales independientes) |
com.hawkersco:pi-function-commons | Utilidades de fecha |
spring-boot-starter-test (test) | JUnit 5 + Spring Test |
5. API / Endpoints
No aplica a este proyecto. Es un batch/runner sin capa REST.
6. Integraciones externas
| Sistema | Protocolo | Dirección | Detalle |
|---|---|---|---|
| Auro (España) | HTTP (AuroClient) | Entrante | Consulta de documentos/estado de envío por pedido |
| LogSolution/Asendia (Italia) | SOAP | Entrante | Consulta de estado de envío |
| Sprint Logistics API v2 (EU y GB, credenciales distintas) | HTTP REST | Entrante | Consulta de estado de envío |
| Cubbo (México) | HTTP REST | Entrante | Consulta de estado de envío |
PostgreSQL (dynamics-pro, logistics) | JDBC | Entrante/Saliente | Lectura de pedidos pendientes de estado final; escritura de ShipmentStatusHistory y OrderStatusPro |
7. Configuración
En producción (application-pro.properties) las credenciales llegan por variables de entorno inyectadas como Secret de Kubernetes; en local (application.properties) el repositorio contiene actualmente valores reales hardcodeados de múltiples carriers (ver alerta de seguridad).
| Clave | Descripción |
|---|---|
recovery.carriers | Lista de procesadores activos (vacío = todos); en local está fijada a auro únicamente |
spring.datasource.* | Credenciales de la BD dynamics-pro (datasource primario) |
logistics.datasource.* | Credenciales de la BD logistics (datasource secundario) |
auro.auth.client.* | Credenciales de Auro |
cubbo.client.* | Credenciales de producción de Cubbo |
logsolution.auth-logistic.client.url | URL del servicio SOAP de LogSolution |
sprintlogistics-v2.api.* / sprintlogistics-gb-v2.api.* | Credenciales de Sprint Logistics EU y GB |
slack.client.url / .auth.token / .channel.report.id | Configuración de Slack (el token de perfil local es un valor placeholder, xoxb-dev-token, no una credencial real) |
⚠️ Alerta de seguridad
El fichero src/main/resources/application.properties (perfil local) contiene actualmente credenciales reales en texto plano de múltiples carriers: Auro, Cubbo (producción), Sprint Logistics EU y GB — las mismas credenciales ya señaladas como expuestas en logistic-erp y proyectos hermanos —, además de las contraseñas de ambas bases de datos PostgreSQL. Ninguno de estos valores se ha reproducido en este documento. Se recomienda:
- Rotar de forma coordinada las credenciales de Auro, Cubbo, Sprint Logistics (EU/GB) y las contraseñas de ambas BD, dado que se comparten con otros proyectos del ecosistema.
- Sustituir los valores hardcodeados de
application.propertiespor credenciales de un entorno de desarrollo aislado. - Revisar el historial de control de versiones, ya que estas credenciales pueden seguir expuestas en commits anteriores.
8. Persistencia
Dos bases de datos PostgreSQL: dynamics-pro (entidad OrderStatusPro) y logistics (Order, Shipment, ShipmentStatusHistory, Carrier), ambas con ddl-auto=none. No hay Flyway/Liquibase en este repositorio.
9. Procesos programados y mensajería
No hay @Scheduled ni listeners de colas: la periodicidad la impone el CronJob de Kubernetes (k8s/cronjob.yaml), que ejecuta el contenedor cada 30 minutos (schedule: "*/30 * * * *"). El flujo común de cada procesador: consulta en logistics los pedidos paginados (500 por página) sin el estado final de su carrier, para cada envío consulta la API/SOAP del carrier correspondiente, mapea el estado devuelto a los códigos internos, y si es un estado nuevo (no registrado ya en ShipmentStatusHistory) lo guarda tanto ahí como en OrderStatusPro (Dynamics), incluyendo la respuesta cruda (JSON, vía Gson) como rawData para auditoría. Los pedidos cuya rawData contiene la cadena de test (lahermanadeaxel) se marcan directamente con todos los estados de la lista, sin llamar realmente a la API del carrier.
10. Ejecución en local
Requisitos previos: JDK 25, Maven, acceso a ambas BD y credenciales válidas de los carriers en un application.properties local.
# Compilar
./mvnw clean install
# Compilar sin tests
./mvnw clean install -DskipTests
# Ejecutar tras compilar
java -Xmx256m -jar target/recovery-logistic-status-1.0.25.jar
# Ejecutar con perfil de producción
java -jar target/recovery-logistic-status-1.0.25.jar --spring.profiles.active=pro
Por defecto en local, recovery.carriers=auro limita la ejecución solo al procesador de Auro; para probar otros carriers hay que ajustar esa propiedad.
11. Despliegue
- Imagen: construida con
jib-maven-plugin(baseeclipse-temurin:25-jre,containerizingMode=packaged), con límites de memoria explícitos vía JVM flags (-Xmx1024m,-XX:MaxMetaspaceSize=128m,-XX:MaxDirectMemorySize=64m,-XX:+ExitOnOutOfMemoryError) — elCLAUDE.mdmenciona un límite de heap de 256MB para un Dockerfileeclipse-temurin:25-jdk-alpineque no coincide con la configuración real vía Jib. - Orquestación: Kubernetes
CronJoben el clúster GKEpi-cluster-hw, namespacepi, ejecutándose cada 30 minutos. - CI/CD (Jenkins): pipeline con escaneo KICS, SonarQube, tests, push de Docker y despliegue, según el propio
CLAUDE.md.
Job de Jenkins: https://jenkins-pi.hawkersco.net/job/recovery-logistic-status/
12. Manejo de errores y logging
No hay una estrategia de excepciones centralizada (no hay @ControllerAdvice, es un runner). RecoveryLogisticStatusOrchestrator captura cualquier excepción de cada procesador de forma independiente y la registra con Level.SEVERE, sin que el fallo de uno afecte a los demás. RecoveryLogisticStatusAuroRunner captura específicamente RestClientException al consultar documentos por pedido, registrando un WARNING y continuando con el siguiente pedido. Logging mediante java.util.logging.Logger estándar (consola).
13. Notas y consideraciones
- Pausa de 1000ms entre llamadas descrita en
CLAUDE.mdno encontrada en el código: el documento afirma que cada runner incluye un "Sleep 1000ms between calls (rate-limit guard)", pero no se ha encontrado ningúnThread.sleepenRecoveryLogisticStatusAuroRunnerni en el resto de clases del paquete raíz. Puede que esta protección se haya eliminado en una refactorización posterior sin actualizar el documento, o que solo aplique a alguno de los runners no revisado en detalle en este documento. - Filtro
recovery.carriersrestringe el comportamiento en local: en local solo se ejecuta el carrierauro; conviene tenerlo presente al depurar localmente para no asumir que los demás carriers no funcionan cuando simplemente están desactivados por configuración. - Ver alerta de seguridad en la sección 7 sobre credenciales reales de múltiples carriers expuestas en
application.properties.