Skip to main content

Feeds Commons

1. Descripción general

feeds-commons es una librería compartida (JAR) del ecosistema de microservicios de Hawkers que centraliza el acceso a la base de datos PostgreSQL de feeds. Expone entidades JPA, repositorios Spring Data y servicios que los servicios consumidores inyectan directamente en su contexto de Spring.

El objetivo es evitar la duplicación de queries y lógica de acceso a datos entre los distintos microservicios que trabajan con feeds de productos, columnas protegidas y redirecciones cortas (HawkeRs). No contiene capa REST, punto de entrada principal ni fichero de configuración propio — la conexión a base de datos la provee siempre el servicio consumidor.

2. Información técnica

PropiedadValor
artifactIdfeeds-commons
groupIdcom.hawkersco
version1.0.25-SNAPSHOT
Java25
Spring Boot4.0.6
Tipo artefactoJAR (librería, sin main)
MódulosProyecto simple (mono-módulo)
RepositorioGCP Artifact Registry (europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven)

3. Arquitectura y diseño

La librería sigue una estructura de tres capas estrictamente separadas bajo el paquete base com.hawkersco.feedscommons:

com.hawkersco.feedscommons
├── dao/ → Entidades JPA + clases @IdClass de clave compuesta
├── repository/ → Interfaces Spring Data CrudRepository
└── service/ → Beans @Service que delegan en los repositorios

No existe capa controller, configuración propia ni punto de entrada. El consumidor importa la dependencia Maven y los beans se registran automáticamente en su contexto de Spring gracias al component-scan estándar de Spring Boot.

graph TD
CS[Servicio consumidor] -->|@Autowired| SVC[Service Bean]
SVC --> REPO[Repository Interface]
REPO -->|Spring Data JPA / Hibernate 7| DB[(PostgreSQL)]

Cada entidad utiliza @IdClass (no @EmbeddedId) para gestionar claves primarias compuestas y cumple Serializable tal y como exige la especificación JPA.

4. Dependencias principales

DependenciaVersiónPropósito
spring-boot-startergestionada por BOM 4.0.6Autoconfiguración base de Spring Boot
spring-boot-starter-data-jpagestionada por BOM 4.0.6Spring Data JPA + Hibernate 7.x como proveedor ORM
org.postgresql:postgresql42.7.11Driver JDBC para PostgreSQL
org.projectlombok:lombok1.18.46Generación de getters/setters/constructores en tiempo de compilación
spring-boot-starter-testgestionada por BOM 4.0.6Scope test — para los servicios consumidores
artifactregistry-maven-wagon2.2.1Extensión Maven para publicar en GCP Artifact Registry

5. API / Endpoints

No aplica a este proyecto.

Esta librería no expone ningún endpoint REST. Es un artefacto de tipo commons pensado para ser importado como dependencia Maven.

6. Integraciones externas

No aplica a este proyecto.

La única integración es con la base de datos PostgreSQL, que es responsabilidad del servicio consumidor configurar. No hay llamadas a APIs externas, colas de mensajería ni otros sistemas.

7. Configuración

Esta librería no incluye application.yml ni application.properties. El servicio consumidor debe proveer la configuración de datasource en su propio fichero de propiedades:

PropiedadDescripciónEjemplo de valor
spring.datasource.urlURL JDBC de la base de datos PostgreSQLjdbc:postgresql://host:5432/feeds_db
spring.datasource.usernameUsuario de la base de datos${DB_USER}
spring.datasource.passwordContraseña de la base de datos${DB_PASSWORD}
spring.jpa.hibernate.ddl-autoEstrategia DDL de Hibernatevalidate o none
spring.jpa.show-sqlLog de queries SQL (solo desarrollo)false

Sin estas propiedades el contexto de Spring del consumidor fallará al arrancar.

8. Persistencia

Base de datos: PostgreSQL (driver 42.7.11).

Entidades y tablas

EntidadTablaCampos clave (@IdClass)Otros campos
FieldFeedfield_feedcountryIso, site, fieldTitlefieldValue, sku
HawkeRsRedirectionhawke_rs_redirectioncode, siteshortUrl, url
ProtectedColumnprotected_columnsite, countryIso, fieldTitle

Nota: FieldFeedId declara sku como parte de la clase de clave compuesta, pero en la entidad FieldFeed el campo sku no está anotado con @Id. Ver sección 13.

Todas las entidades implementan Serializable y usan anotaciones jakarta.persistence.* (Jakarta EE 10+).

No existen migraciones Flyway ni Liquibase en esta librería. El esquema se asume preexistente en la base de datos del consumidor.

API de repositorios

FieldFeedRepository

List<FieldFeed> findBySiteAndCountryIsoOrderBySku(String site, String countryIso);

HawkeRsRedirectionRepository

HawkeRsRedirection findTop1ByCodeAndSite(String code, String site);

ProtectedColumnRepository

List<ProtectedColumn> findBySiteOrderByCountryIso(String site);
List<ProtectedColumn> findBySiteAndCountryIsoOrderByCountryIso(String site, String countryIso);
List<ProtectedColumn> findBySiteAndCountryIsoOrderByFieldTitle(String site, String countryIso);

API de servicios

Los servicios son finas capas de delegación sobre los repositorios:

FieldFeedService

MétodoDescripción
save(FieldFeed)Persiste o actualiza un registro field_feed
delete(FieldFeed)Elimina un registro field_feed
findBySiteAndCountryIsoOrderBySku(site, countryIso)Devuelve todos los feeds de un sitio y país, ordenados por SKU

HawkeRsRedirectionService

MétodoDescripción
findTop1ByCodeAndSite(code, site)Devuelve la primera redirección que coincide con el código corto y el sitio

ProtectedColumnService

MétodoDescripción
save(ProtectedColumn)Persiste o actualiza una columna protegida
findBySiteOrderByCountryIso(site)Devuelve todas las columnas protegidas de un sitio, ordenadas por país
findBySiteAndCountryIsoOrderByCountryIso(site, countryIso)Filtra por sitio y país, ordena por país
findBySiteAndCountryIsoOrderByFieldTitle(site, countryIso)Filtra por sitio y país, ordena por título de campo

9. Procesos programados y mensajería

No aplica a este proyecto.

No hay jobs @Scheduled, listeners de Kafka/RabbitMQ ni runners batch.

10. Ejecución en local

Esta librería no es un servicio ejecutable. No tiene main ni servidor embebido.

Para compilar e instalar en el repositorio local Maven:

./mvnw clean install -DskipTests

Para compilar con tests (requiere PostgreSQL accesible con las propiedades de datasource configuradas):

./mvnw clean install

Para publicar en GCP Artifact Registry (requiere credenciales GCP configuradas):

mvn deploy -DskipTests

Para consumir la librería desde otro proyecto, añadir al pom.xml del consumidor:

<dependency>
<groupId>com.hawkersco</groupId>
<artifactId>feeds-commons</artifactId>
<version>1.0.25-SNAPSHOT</version>
</dependency>

11. Despliegue

El pipeline de CI/CD está definido en el Jenkinsfile del repositorio. Utiliza el agente any con las herramientas JDK25 y Maven3 configuradas en Jenkins.

Etapas del pipeline:

EtapaDescripción
CheckoutDescarga el código fuente del repositorio
Publish to Artifact RegistryEjecuta mvn deploy -DskipTests y publica el JAR en GCP Artifact Registry

El artefacto se publica en:

artifactregistry://europe-west3-maven.pkg.dev/pi-saldum/pi-repo-maven

Job de Jenkins:

https://jenkins-pi.hawkersco.net/job/feeds-commons/

12. Manejo de errores y logging

No hay gestión de excepciones propia ni configuración de logging en esta librería. Los errores JPA/JDBC (entidad no encontrada, violación de constraint, problema de conexión) se propagan como excepciones estándar de Spring Data (DataAccessException y subtipos) al servicio consumidor, que es el responsable de capturarlas y gestionarlas.

El logging de queries SQL puede activarse en el consumidor mediante spring.jpa.show-sql=true.

13. Notas y consideraciones

  • Inconsistencia en FieldFeedId: La clase de clave compuesta FieldFeedId declara cuatro campos: countryIso, site, fieldTitle y sku. Sin embargo, en la entidad FieldFeed solo countryIso, site y fieldTitle están anotados con @Id; sku no lo está. Esto es técnicamente inconsistente según la especificación JPA para @IdClass y puede provocar comportamiento inesperado en Hibernate al calcular la identidad de la entidad. Pendiente de revisar si sku debe formar parte de la PK o eliminarse de FieldFeedId.

  • Uso de @Autowired en lugar de inyección por constructor: Los servicios usan @Autowired sobre campo, patrón desaconsejado desde Spring 4.x en favor de inyección por constructor (mejor testabilidad y detección temprana de dependencias circulares).

  • Sin tests propios: La librería no contiene ningún test. La dependencia spring-boot-starter-test está declarada en scope test pensando en los consumidores, no en esta librería. Sería recomendable añadir tests de integración con una base de datos embebida (H2 en modo PostgreSQL o Testcontainers).

  • HawkeRsRedirectionRepository.findTop1ByCodeAndSite retorna null: El método puede devolver null en lugar de Optional<HawkeRsRedirection>. Los consumidores deben comprobarlo explícitamente para evitar NullPointerException.