Labelary Client
1. Descripción general
labelary-client es una librería cliente reutilizable (JAR) que encapsula la comunicación con la API pública de Labelary, servicio de conversión de etiquetas para impresoras Zebra. El proyecto no expone ningún endpoint REST propio; se publica en el registro de artefactos Maven interno y es consumido por otros microservicios del ecosistema Hawkers que necesiten generar etiquetas de envío en formato ZPL/PDF a partir de HTML o convertir imágenes a dicho formato.
Expone tres operaciones:
- Conversión de un documento HTML a ZPL/PDF (endpoint principal de etiqueta 4x6 con índice).
- Conversión alternativa de HTML a ZPL/PDF (mismo formato de etiqueta, sin índice en la ruta).
- Conversión de una imagen (multipart) al formato de salida de Labelary.
2. Información técnica
| Propiedad | Valor |
|---|---|
artifactId | labelary-client |
groupId | com.hawkersco |
version | 1.0.25-SNAPSHOT |
| Java | 25 |
| Spring Boot | 4.0.6 |
| Tipo de artefacto | JAR (librería, no ejecutable) |
| Módulos | Proyecto único (no multi-módulo) |
3. Arquitectura y diseño
Estructura del proyecto:
com.hawkersco.labelaryclient
├── LabelaryClientApplication.java # Clase @SpringBootApplication (residual, sin lógica)
├── client/
│ └── LabelaryClient.java # Interfaz @HttpExchange: convertToZpl, convertToZplAlt, convertImageToPdf
└── config/
├── LabelaryClientAutoConfiguration.java # @AutoConfiguration principal
└── LabelaryClientConfig.java # Clase vacía sin anotación, marcada como reemplazada
Flujo principal
sequenceDiagram
participant Consumidor as Microservicio consumidor
participant Client as LabelaryClient
participant API as API Labelary
Consumidor->>Client: convertToZpl(html) / convertImageToPdf(file)
alt Endpoint distinto de /v1/graphics
Client->>API: POST /v1/printers/8dpmm/labels/4x6/(0/) + Accept: application/pdf + Content-Type: application/x-www-form-urlencoded
else Endpoint /v1/graphics
Client->>API: POST /v1/graphics (multipart/form-data, sin override de cabeceras)
end
API-->>Client: byte[] (PDF/ZPL/imagen)
Client-->>Consumidor: ResponseEntity<byte[]>
La autoconfiguración (LabelaryClientAutoConfiguration) se activa condicionalmente con @ConditionalOnProperty(prefix = "labelary.client", name = "url"), registrando el bean LabelaryClient con un RestClient cuyo requestInterceptor inspecciona la ruta de cada petición:
request.getHeaders().set(HttpHeaders.ACCEPT, "application/pdf");
request.getHeaders().set(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
Estas cabeceras solo se fuerzan cuando la ruta no contiene /v1/graphics; para el endpoint de gráficos no se establece ninguna cabecera adicional en el interceptor, dejando que @PostExchange(contentType = "multipart/form-data") gestione el Content-Type de la petición.
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
LabelaryClientConfig es una clase package-private sin anotación @Configuration y con el comentario // Replaced by LabelaryClientAutoConfiguration: es código muerto que no participa en el contexto de Spring (ver sección 13).
4. Dependencias principales
| Dependencia | Versión | Propósito |
|---|---|---|
spring-boot-starter | (gestionada SB4) | Base de Spring Boot (contexto, autoconfiguración) |
spring-web | (gestionada SB4) | RestClient + @HttpExchange / HttpServiceProxyFactory / soporte multipart |
spring-boot-starter-test | (gestionada SB4) | Testing (scope test) |
5. API / Endpoints
No aplica a este proyecto. labelary-client es una librería cliente JAR que no expone endpoints REST propios. Las operaciones que encapsula sobre la API de Labelary se detallan en la sección 6.
6. Integraciones externas
API pública de Labelary
| Método cliente | HTTP | Ruta remota | Dirección | Descripción |
|---|---|---|---|---|
convertToZpl | POST | /v1/printers/8dpmm/labels/4x6/0/ | Saliente | Convierte un documento HTML a etiqueta ZPL/PDF (8dpmm, 4x6", índice 0) |
convertToZplAlt | POST | /v1/printers/8dpmm/labels/4x6/ | Saliente | Conversión alternativa de HTML a ZPL/PDF (misma resolución/tamaño, sin índice) |
convertImageToPdf | POST | /v1/graphics | Saliente | Convierte un fichero de imagen (multipart) al formato de salida de Labelary |
Request convertToZpl / convertToZplAlt: cuerpo String con el documento HTML a renderizar como etiqueta, enviado como application/x-www-form-urlencoded con Accept: application/pdf.
Request convertImageToPdf:
ResponseEntity<byte[]> resultado = labelaryClient.convertImageToPdf(multipartFile);
Petición multipart/form-data con la parte file conteniendo la imagen a convertir.
Response (todas las operaciones): ResponseEntity<byte[]> — el cuerpo binario devuelto por Labelary (PDF, ZPL o imagen convertida, según el endpoint). El cliente no interpreta ni valida el contenido; lo entrega tal cual al consumidor.
Protocolo: HTTPS REST. Formato: application/x-www-form-urlencoded (HTML) / multipart/form-data (imagen) en el request; respuesta binaria (byte[]). Autenticación: Ninguna implementada en el cliente (API pública de Labelary sin credenciales).
7. Configuración
No se incluye ningún application.properties/application.yml en la librería. La única propiedad requerida debe ser suministrada por la aplicación consumidora:
| Propiedad | Descripción | Ejemplo de valor |
|---|---|---|
labelary.client.url | URL base de la API de Labelary (activa la autoconfiguración) | ${LABELARY_CLIENT_URL} |
Variables de entorno recomendadas
| Variable | Propiedad mapeada |
|---|---|
LABELARY_CLIENT_URL | labelary.client.url |
Importante: Si
labelary.client.urlno está definida, el beanLabelaryClientno se registra (condición@ConditionalOnProperty).
8. Persistencia
No aplica a este proyecto. La librería no accede a ninguna base de datos ni mantiene estado en memoria. LabelaryClientApplication no excluye explícitamente DataSourceAutoConfiguration en el código actual — al no incluir ningún starter de datos, Spring Boot no intenta configurar ningún DataSource.
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
labelary-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 sin tests
./mvnw -B -DskipTests clean install
# Compilar con tests
./mvnw clean verify
Uso como dependencia en un microservicio consumidor
<dependency>
<groupId>com.hawkersco</groupId>
<artifactId>labelary-client</artifactId>
<version>1.0.25-SNAPSHOT</version>
</dependency>
La autoconfiguración se activa automáticamente al declarar labelary.client.url en la aplicación consumidora.
11. Despliegue
El pipeline de Jenkins (Jenkinsfile) consta de dos etapas:
- Checkout — descarga el código del repositorio.
- Publish to Artifact Registry — ejecuta
mvn deploy -DskipTestspara publicar el JAR en Google Artifact Registry.
| Parámetro | Valor |
|---|---|
| JDK | JDK25 (tool Jenkins) |
| Maven | Maven3 (tool Jenkins) |
| Repositorio | europe-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/labelary-client/
12. Manejo de errores y logging
La librería no implementa ninguna estrategia propia de manejo de excepciones ni logging estructurado. Las excepciones de red o HTTP propagadas por RestClient (como RestClientResponseException) son responsabilidad del servicio consumidor. No hay configuración de logback ni de niveles de log específicos.
13. Notas y consideraciones
-
LabelaryClientConfiges código muerto: La clase existe como package-private, sin anotación@Configurationni ninguna otra anotación de Spring, con el único contenido siendo un comentario// Replaced by LabelaryClientAutoConfiguration. No participa en el contexto de Spring y podría eliminarse sin impacto funcional. -
Cabeceras no explícitas en el endpoint de gráficos: El
requestInterceptordeLabelaryClientAutoConfigurationsolo fuerzaAccept: application/pdfyContent-Type: application/x-www-form-urlencodedpara las rutas que no contienen/v1/graphics. Para/v1/graphics, ninguna cabeceraAcceptse establece explícitamente en el interceptor, a diferencia de lo indicado en la documentación previa del proyecto (CLAUDE.md), que mencionabaAccept: application/pngpara este endpoint — dicho comportamiento no se encuentra en el código actual. Pendiente de verificar si se eliminó en una refactorización posterior. -
LabelaryClientApplicationsin cuerpo: La clase principal@SpringBootApplicationno contiene ningún métodomain, a diferencia de otros clientes del ecosistema. Es un artefacto residual de la generación inicial del proyecto con Spring Initializr, sin función operativa. -
Endpoints "duplicados" para HTML→ZPL:
convertToZplyconvertToZplAltapuntan a rutas casi idénticas (/v1/printers/8dpmm/labels/4x6/0/vs/v1/printers/8dpmm/labels/4x6/), ambas devolviendoResponseEntity<byte[]>. La diferencia semántica entre ambas (más allá del índice de etiqueta en la ruta) no está documentada en el código — pendiente de verificar en la documentación oficial de Labelary. -
Sin manejo de tamaño/resolución configurable: Los valores
8dpmm(densidad) y4x6(tamaño de etiqueta) están hardcodeados en las constantes de ruta deLabelaryClient. Cualquier necesidad de otra densidad o tamaño de etiqueta requeriría modificar el código de la librería. -
Sin tests implementados: El directorio
src/test/no existe. La dependenciaspring-boot-starter-testestá declarada pero no hay ninguna prueba. -
Sin autenticación: El cliente no implementa ningún mecanismo de autenticación hacia la API de Labelary, consistente con que se trata de un servicio público sin credenciales.