Skip to main content

Servientrega Client

1. Descripción general

servientrega-client es una librería cliente reutilizable (JAR) que encapsula la comunicación con el servicio web SOAP de Servientrega, transportista logístico colombiano integrado en el ecosistema de microservicios de Hawkers. El proyecto no expone ningún endpoint REST propio; se publica en el registro de artefactos Maven interno y es consumido por otros microservicios que necesiten validar/enviar salidas (pedidos de envío) y consultar su tracking en el sistema de Servientrega.

El host remoto (wms.servientrega.com) requiere una configuración TLS especial: la librería desactiva la validación de certificados para las peticiones que realiza, ver detalle y consideración de seguridad en la sección 13.

2. Información técnica

PropiedadValor
artifactIdservientrega-client
groupIdcom.hawkersco
version1.0.25-SNAPSHOT
Java25
Spring Boot4.0.6
Tipo de artefactoJAR (librería, no ejecutable)
MódulosProyecto único (no multi-módulo)

3. Arquitectura y diseño

Estructura del proyecto:

com.hawkersco.servientregaclient
├── ServientregaClientApplication.java # Clase @SpringBootApplication (residual, sin lógica)
├── client/
│ └── ServientregaSoapClient.java # Interfaz @HttpExchange: sendOrder, trackingSalidas
├── config/
│ ├── ServientregaAutoConfiguration.java # @AutoConfiguration principal (SSL trust-all + resolver de ParamsForm)
│ ├── ParamsFormArgumentResolver.java # HttpServiceArgumentResolver que expande ParamsForm en query params planos
│ ├── NaiveSSLSocketFactory.java # Utilidad SSL heredada, no instanciada por la autoconfiguración actual (ver sección 13)
│ ├── NaiveHostnameVerifier.java # Utilidad heredada, no instanciada por la autoconfiguración actual (ver sección 13)
│ └── ServientregaSoapConfig.java # Clase vacía, retenida solo por compatibilidad (comentario explícito en el código)
└── entity/
├── ParamsForm.java # Parámetros de autenticación/config enviados como query params
├── Salidas.java # Envelope SOAP de request para validarSalidas
└── SalidasResponse.java # Envelope SOAP de response para validarSalidas

Flujo principal

sequenceDiagram
participant Consumidor as Microservicio consumidor
participant Resolver as ParamsFormArgumentResolver
participant Client as ServientregaSoapClient
participant API as wms.servientrega.com

Consumidor->>Client: sendOrder(xmlSalidas, paramsForm) / trackingSalidas(xmlTracking, paramsForm)
Client->>Resolver: expande ParamsForm en params.login, params.use, params.password, ...
Client->>API: POST /suite/webservices/salidas.php | trackingsalidas.php (query params + XML body, TLS sin validar certificado)
API-->>Client: ResponseEntity<String> (XML crudo)
Client-->>Consumidor: ResponseEntity<String>

La autoconfiguración (ServientregaAutoConfiguration) se activa condicionalmente con @ConditionalOnProperty(prefix = "logisticco.servientrega.client", name = "url"), registrando el bean ServientregaSoapClient con:

  • Un RestClient cuya requestFactory es un JdkClientHttpRequestFactory construido con un SSLContext que confía en cualquier certificado (X509TrustManager sin validación) y con verificación de hostname desactivada (SSLParameters.setEndpointIdentificationAlgorithm("")).
  • Un customArgumentResolver (ParamsFormArgumentResolver) que, al recibir un parámetro ParamsForm en un método @HttpExchange, lo expande en los query params planos params.login, params.use, params.password, params.style, params.uri y params.location — replicando el comportamiento que antes ofrecía Spring Cloud OpenFeign al anotar un POJO con @RequestParam.

El registro de la autoconfiguración se realiza mediante el fichero estándar de Spring Boot:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

4. Dependencias principales

DependenciaVersiónPropósito
spring-boot-starter(gestionada SB4)Base de Spring Boot (contexto, autoconfiguración)
spring-web(gestionada SB4)RestClient + @HttpExchange / HttpServiceProxyFactory / HttpServiceArgumentResolver
jakarta.xml.bind:jakarta.xml.bind-api4.0.1Anotaciones JAXB para el mapeo XML/SOAP de Salidas/SalidasResponse
org.projectlombok:lombok1.18.46Generación de boilerplate en los modelos (getters, setters, constructores)
spring-boot-starter-test(gestionada SB4)Testing (scope test)

5. API / Endpoints

No aplica a este proyecto. servientrega-client es una librería cliente JAR que no expone endpoints REST propios. Las operaciones SOAP que encapsula se detallan en la sección 6.

6. Integraciones externas

Servicio web SOAP de Servientrega (wms.servientrega.com)

Método clienteHTTPRuta remotaDescripción
sendOrderPOST/suite/webservices/salidas.phpValida y envía una salida (pedido de envío) — operación SOAP validarSalidas
trackingSalidasPOST/suite/webservices/trackingsalidas.phpConsulta el tracking de salidas existentes

Ambos métodos reciben el cuerpo XML SOAP completo como String (@RequestBody, construido por el consumidor a partir de los POJOs JAXB Salidas) y un objeto ParamsForm que se expande automáticamente en query params de autenticación (params.login, params.use, params.password, params.style, params.uri, params.location).

Ejemplo de estructura del envelope SOAP para sendOrder (simplificado, a partir de Salidas):

<soapenv:Envelope xmlns:soapenv="..." xmlns:sal="...">
<soapenv:Header/>
<soapenv:Body>
<sal:validarSalidas>
<arreglo_salidas>
<punto>1</punto>
<salida>ORD-000123</salida>
<identificacion>1234567890</identificacion>
<nombre>Cliente</nombre>
<apellido>Final</apellido>
<direccion>Calle Ejemplo 1</direccion>
<ciudad>Bogotá</ciudad>
<pais>CO</pais>
<detalles>
<secuencia>1</secuencia>
<articulo>SKU-001</articulo>
<cantidad>2</cantidad>
<valor_base>19.99</valor_base>
</detalles>
</arreglo_salidas>
</sal:validarSalidas>
</soapenv:Body>
</soapenv:Envelope>

Ejemplo de estructura de respuesta (SalidasResponse):

<Envelope>
<Body>
<validarSalidasResponse>
<arreglo_respuestas>
<punto>1</punto>
<salida>ORD-000123</salida>
<estado>OK</estado>
<mensaje>Salida registrada correctamente</mensaje>
</arreglo_respuestas>
</validarSalidasResponse>
</Body>
</Envelope>

trackingSalidas no dispone de un POJO JAXB de respuesta propio en este proyecto: devuelve ResponseEntity<String> con el XML crudo.

Protocolo: SOAP sobre HTTPS (text/xml;charset=UTF-8), con validación de certificado TLS desactivada para el host de Servientrega. Autenticación: credenciales (login, password) enviadas como query params planos derivados de ParamsForm.

7. Configuración

No se incluye ningún application.properties/application.yml en la librería. Las propiedades deben ser inyectadas por la aplicación consumidora.

Propiedades requeridas

PropiedadDescripciónEjemplo de valor
logisticco.servientrega.client.urlURL base del servicio SOAP Servientrega (activa la autoconfiguración)${SERVIENTREGA_CLIENT_URL}

Las credenciales (login, password, use, style, uri, location) no se configuran como propiedades Spring: el consumidor debe construir un objeto ParamsForm con estos valores y pasarlo en cada llamada.

Variables de entorno recomendadas

VariablePropiedad mapeada
SERVIENTREGA_CLIENT_URLlogisticco.servientrega.client.url

Importante: Si logisticco.servientrega.client.url no está definida, el bean ServientregaSoapClient no se registra (condición @ConditionalOnProperty).

Logging detallado

Para obtener el equivalente al nivel FULL de logging que ofrecía la antigua integración con OpenFeign, CLAUDE.md recomienda:

logging.level.org.springframework.web.client.RestClient=DEBUG

8. Persistencia

No aplica a este proyecto. La librería no accede a ninguna base de datos ni mantiene estado en memoria.

9. Procesos programados y mensajería

No aplica a este proyecto. No existen jobs @Scheduled, listeners de colas/topics ni runners batch.

10. Ejecución en local

servientrega-client es una librería JAR, no una aplicación ejecutable. No tiene servidor embebido ni endpoint de health.

Requisitos previos

  • Java 25
  • Maven 3.x
  • Acceso al registro de artefactos Maven interno (europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven) para resolver/publicar dependencias.

Compilar e instalar en repositorio local

# Compilar e instalar
./mvnw clean install

# Compilar sin tests (como en CI)
./mvnw -B -DskipTests clean install

# Ejecutar tests
./mvnw test

Uso como dependencia en un microservicio consumidor

<dependency>
<groupId>com.hawkersco</groupId>
<artifactId>servientrega-client</artifactId>
<version>1.0.25-SNAPSHOT</version>
</dependency>

La autoconfiguración se activa automáticamente al declarar logisticco.servientrega.client.url en la aplicación consumidora; ya no es necesario @EnableFeignClients.

11. Despliegue

El pipeline de Jenkins (Jenkinsfile) consta de dos etapas:

  1. Checkout — descarga el código del repositorio.
  2. Publish to Artifact Registry — ejecuta mvn deploy -DskipTests para publicar el JAR en Google Artifact Registry.

CLAUDE.md menciona que el build se ejecuta vía jenkins/scripts/mvn.sh, script no presente en este repositorio ni referenciado directamente en el Jenkinsfile actual. Se documenta el Jenkinsfile realmente presente.

ParámetroValor
JDKJDK25 (tool Jenkins)
MavenMaven3 (tool Jenkins)
Repositorioeurope-west3-maven.pkg.dev/pi-saldum/pi-repo-maven (Artifact Registry GCP)

No existe Dockerfile ni despliegue como servicio independiente; el artefacto es un JAR publicado en el registro Maven.

Job de Jenkins:

https://jenkins-pi.hawkersco.net/job/servientrega-client/

12. Manejo de errores y logging

La librería no implementa ninguna estrategia propia de manejo de excepciones ni logging estructurado más allá de la recomendación de habilitar DEBUG sobre RestClient para depuración (ver sección 7). Las excepciones de red o HTTP propagadas por RestClient (como RestClientResponseException) son responsabilidad del servicio consumidor, ya que ningún método de ServientregaSoapClient declara throws explícito.

13. Notas y consideraciones

  • Validación de certificado TLS desactivada para todo el cliente: ServientregaAutoConfiguration construye un SSLContext que confía en cualquier certificado y desactiva la verificación de hostname (setEndpointIdentificationAlgorithm("")) para todas las peticiones del RestClient (no solo para un host concreto). Dado que la baseUrl de este cliente está siempre fijada al host de Servientrega vía logisticco.servientrega.client.url, el efecto práctico queda acotado a ese host, pero expone al consumidor a riesgo de man-in-the-middle si dicha URL apuntase alguna vez a un host distinto o si el tráfico se intercepta en la red. El comentario del propio código indica que esto reproduce intencionalmente el comportamiento previo con Feign, sugiriendo que el certificado de wms.servientrega.com es autofirmado o está mal configurado en origen.

  • NaiveSSLSocketFactory y NaiveHostnameVerifier no están en uso: Ambas clases implementan un enfoque más granular (confiar únicamente en hostnames concretos pasados por parámetro, delegando el resto al comportamiento por defecto de la JVM), pero no son instanciadas por ServientregaAutoConfiguration, que en su lugar construye su propio SSLContext/SSLParameters inline con un alcance más amplio (todo el RestClient, no por hostname). Son código retenido de la integración anterior con Feign, documentado como tal en el propio código, y podrían eliminarse sin impacto si se confirma que ningún otro componente las usa.

  • ServientregaSoapConfig como stub vacío documentado: La clase está vacía y su Javadoc indica explícitamente que se retiene solo por compatibilidad hacia atrás, con la configuración real ahora en ServientregaAutoConfiguration — mismo patrón de placeholder "muerto pero documentado" observado en privalia-marketplace-client.

  • trackingSalidas sin modelo de respuesta tipado: A diferencia de sendOrder (que tiene SalidasResponse), la operación de tracking no cuenta con ningún POJO JAXB de respuesta en este proyecto — el consumidor recibe el XML crudo y debe parsearlo por su cuenta.

  • Expansión de ParamsForm acoplada a nombres de campo fijos: ParamsFormArgumentResolver construye los nombres de query param (params.login, params.use, etc.) de forma manual y explícita por cada campo de ParamsForm.Params — cualquier campo nuevo que se añada a Params requeriría actualizar también el resolver, ya que no hay reflexión ni generación automática.

  • Sin tests implementados: No se ha encontrado directorio src/test/ en el proyecto.

  • ServientregaClientApplication.java: Clase principal de Spring Boot en el paquete raíz, sin funcionalidad operativa. Artefacto residual de la generación inicial del proyecto con Spring Initializr, mismo patrón observado en otros clientes del ecosistema.