Skip to main content

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

CampoValor
artifactIdrecovery-logistic-status
groupIdcom.hawkersco
version1.0.25
Java25 (maven.compiler.release=25)
Spring Boot4.0.6
Tipo de artefactojar (ejecutable, Spring Boot batch/CLI)
MódulosNo 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 propiedad recovery.carriers (vacío = todos), y los ejecuta en paralelo con un ExecutorService dimensionado al número de procesadores activos.
  • 6 runners, cada uno implementando RecoveryLogisticStatusProcessor para un carrier:
Runner (getName())CarrierEstados 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
  • .configDynamicsDbConfig (datasource primario dynamics-pro), LogisticsDbConfig (datasource secundario logistics), RecoveryLogisticStatusConfig.
  • .utilRecoveryLogisticStatusUtil (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

DependenciaPropósito
spring-boot-starterNúcleo de Spring Boot (sin web, es un runner CLI)
com.hawkersco:logistics-commonsEntidades/servicios de la BD logistics
com.hawkersco:dynamics-commonsEntidad/servicio OrderStatusPro de la BD dynamics-pro
com.hawkersco:auro-clientCliente para Auro (España y lentes)
com.hawkersco:cubbo-clientCliente para Cubbo
com.hawkersco:logsolution-clientCliente SOAP para LogSolution
com.hawkersco:sprintlogistics-clientCliente para Sprint Logistics (EU y GB, credenciales independientes)
com.hawkersco:pi-function-commonsUtilidades 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

SistemaProtocoloDirecciónDetalle
Auro (España)HTTP (AuroClient)EntranteConsulta de documentos/estado de envío por pedido
LogSolution/Asendia (Italia)SOAPEntranteConsulta de estado de envío
Sprint Logistics API v2 (EU y GB, credenciales distintas)HTTP RESTEntranteConsulta de estado de envío
Cubbo (México)HTTP RESTEntranteConsulta de estado de envío
PostgreSQL (dynamics-pro, logistics)JDBCEntrante/SalienteLectura 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).

ClaveDescripción
recovery.carriersLista 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.urlURL 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.idConfiguració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:

  1. 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.
  2. Sustituir los valores hardcodeados de application.properties por credenciales de un entorno de desarrollo aislado.
  3. 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 (base eclipse-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) — el CLAUDE.md menciona un límite de heap de 256MB para un Dockerfile eclipse-temurin:25-jdk-alpine que no coincide con la configuración real vía Jib.
  • Orquestación: Kubernetes CronJob en el clúster GKE pi-cluster-hw, namespace pi, 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.md no 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ún Thread.sleep en RecoveryLogisticStatusAuroRunner ni 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.carriers restringe el comportamiento en local: en local solo se ejecuta el carrier auro; 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.