Social Bot Scheduler

🧩 Caso 10: ☕ Java (Spring Boot) → 🌉 n8n → 🟣 Kotlin (Ktor) + PostgreSQL#

Status: Ready Language: Java Language: Kotlin Database: PostgreSQL

Cobertura del ecosistema JVM — el hueco más grande de la matriz original. Contrasta el stack enterprise bloqueante (Spring Boot MVC) con el moderno no-bloqueante (Ktor + corrutinas sobre Netty), persistiendo en PostgreSQL.


🏗️ Arquitectura del Flujo#

  1. 📤 Origenorigin/src/main/java/socialbot/OrderPublisher.java: app Spring Boot (MVC + RestTemplate) que lee posts.json y reenvía los posts vencidos al webhook de n8n.
  2. 🌉 Puenten8n: guardrails canónicos (fingerprint → circuit breaker → idempotencia → HTTP con reintentos → DLQ).
  3. 📥 Destinodest/src/main/kotlin/Application.kt: servidor Ktor (Netty, corrutinas) que expone el contrato REST y persiste vía JDBC.
  4. 📁 PersistenciaPostgreSQL 16: tabla social_posts con INSERT ... ON CONFLICT (idempotente).

Nota

El receptor se empaqueta como fat-jar (plugin Shadow) sobre un runtime eclipse-temurin:21-jre-alpine.


🚀 Cómo levantarlo#

bash
docker-compose --profile case10 up -d      # PostgreSQL + receptor Ktor
ServicioRolPuerto host
db-postgres-10PostgreSQL 16interno
dest-ktor-10Ktor + dashboard8090

Probar el emisor Spring Boot (opcional)#

bash
cd cases/10-java-to-kotlin/origin
WEBHOOK_URL=http://localhost:5678/webhook/social-bot-scheduler-ktor gradle bootRun

🎯 Objetivos didácticos#

  • Bloqueante vs no-bloqueante: Spring MVC (un hilo por request) frente a Ktor (corrutinas sobre event-loop).
  • Interoperabilidad JVM: dos runtimes JVM independientes hablando por HTTP, sin compartir JVM.
  • PostgreSQL idempotente: ON CONFLICT (id) DO UPDATE a nivel de BD.

⚠️ Consideraciones (modelo del laboratorio)#

  • Puerto 8090 = 8080 + 10 (regla canónica, ver docs/PORTS.md).
  • Bind a 127.0.0.1; el receptor valida id/text (→ HTTP 422) como defensa en profundidad.

✅ Estado#

Implementado y verificado (build + boot + health). Parte del Lote 2 del roadmap v5.0 → v4.6.