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.