Este proyecto demuestra cómo aplicar patrones de diseño clásicos —como Strategy, Factory y Observer— en un contexto de arquitectura orientada a eventos. Usa Spring WebFlux para procesamiento reactivo y AWS SQS como bus de eventos (simulado localmente con LocalStack).
Su propósito es servir como referencia práctica y base de aprendizaje para construir arquitecturas desacopladas, escalables y resilientes donde los eventos son el centro de la comunicación entre componentes.
- Patrones de diseño aplicados a eventos:
Implementar Strategy + Factory para enrutar eventos dinámicamente según su tipo (PSE, PayPal, Tarjeta, etc.). - Arquitectura limpia:
Separar responsabilidades en capas (modelos, casos de uso, adaptadores) para favorecer el desac acoplamiento. - Procesamiento reactivo:
Usar Spring WebFlux y Reactor Context para propagar contexto y trazabilidad (messageId,spanId) entre hilos. - Infraestructura local reproducible:
Integrar LocalStack para simular SQS y probar el flujo completo sin depender de AWS real. - Base de entrenamiento:
Servir como ejemplo de referencia para formación técnica o PoC de arquitecturas event-driven.
- Strategy Pattern:
Permite procesar distintos tipos de transacción (Tarjeta, PayPal, PSE…) usando estrategias independientes. - Factory Pattern:
Centraliza la selección de la estrategia adecuada para cada evento entrante. - Observer / Event-Driven:
Los productores publican mensajes en SQS; los consumidores reaccionan de forma asíncrona sin acoplamiento. - Context Propagation:
Propagación automática demessageIdyspanIdmediante Micrometer + Reactor Context.
📦event-driven-design-patterns
┣ 📂applications
┃ ┗ 📂app-service
┃ ┃ ┣ 📂src
┃ ┃ ┃ ┣ 📂main
┃ ┃ ┃ ┃ ┣ 📂java
┃ ┃ ┃ ┃ ┃ ┗ 📂co.com.eventdriven.designpatterns
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📂config
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜[configs and beans]
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜MainApplication.java
┃ ┃ ┃ ┃ ┗ 📂resources
┃ ┃ ┃ ┃ ┃ ┣ 📜[properties]
┃ ┃ ┃ ┗ 📂test
┃ ┃ ┃ ┃ ┗ 📂java
┃ ┃ ┃ ┃ ┃ ┗ 📂co.com.eventdriven.designpatterns
┃ ┃ ┗ 📜build.gradle
┣ 📂deployment
┃ ┣ 📜[Dockerfile, Pipelines as a code]
┣ 📂domain
┃ ┣ 📂model
┃ ┃ ┣ 📂src
┃ ┃ ┃ ┣ 📂main
┃ ┃ ┃ ┃ ┗ 📂java
┃ ┃ ┃ ┃ ┃ ┗ 📂co.com.eventdriven.designpatterns
┃ ┃ ┃ ┗ 📂test
┃ ┃ ┃ ┃ ┗ 📂java
┃ ┃ ┃ ┃ ┃ ┗ 📂co.com.eventdriven.designpatterns
┃ ┃ ┗ 📜build.gradle
┃ ┗ 📂usecase
┃ ┃ ┣ 📂src
┃ ┃ ┃ ┣ 📂main
┃ ┃ ┃ ┃ ┗ 📂java
┃ ┃ ┃ ┃ ┃ ┗ 📂co.com.eventdriven.designpatterns
┃ ┃ ┃ ┗ 📂test
┃ ┃ ┃ ┃ ┗ 📂java
┃ ┃ ┃ ┃ ┃ ┗ 📂co.com.eventdriven.designpatterns
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📂usecase
┃ ┃ ┗ 📜build.gradle
┣ 📂infrastructure
┃ ┣ 📂driven-adapters
┃ ┣ 📂entry-points
┃ ┗ 📂helpers
┣ 📜.gitignore
┣ 📜build.gradle
┣ 📜gradle.properties
┣ 📜lombok.config
┣ 📜main.gradle
┣ 📜README.md
┗ 📜settings.gradle
- Java 21 + Spring Boot / WebFlux
- AWS SQS (simulado con LocalStack)
- Gradle para build modular
- Lombok para simplificar modelos
- Micrometer Context Propagation para propagación de contexto
- LogstashEncoder / Logback para logs estructurados en JSON
- Productor envía evento a SQS (
sqs-payment-events-local). - SQSPaymentFilteringProcessor consume el mensaje y aplica la Factory para elegir la estrategia adecuada.
- Cada Strategy (ej:
CardTransactionStrategy,PaypalTransactionStrategy) procesa el evento con pasos definidos (doOnNext). - Los datos se transforman en un DTO común (
PaymentTransactionInfo) listo para persistencia o integración.
-
Levantar LocalStack y crear cola SQS:
sh LocalStackStartEnvironment.sh
-
Enviar mensaje de pago por tarjeta:
sh LocalStackPhysicalCardPaymentEvent.sh
-
Enviar mensaje de pago por Paypal:
sh LocalStackPaypalPaymentEvent.sh
-
Enviar mensaje de pago por PSE:
sh LocalStackPSEPaymentEvent.sh
-
Purgar SQS (Opcional):
sh LocalStackPurgeSQSQueue.sh
-
Ejecutar aplicación Spring Boot:
./gradlew bootRun
- Logs en formato JSON con
messageIdyspanIdpropagados automáticamente. - Cada Strategy imprime pasos relevantes con
doOnNext(...)para trazabilidad de negocio.
- Añadir persistencia (ej. DynamoDB, MongoDB) para registrar resultados de cada evento.
- Consumir servicios externos para extraer data como ejecución de alguna de las strategies.
- Integrar métricas y dashboards con Micrometer + Prometheus.