← Volver al índice | Arquitectura IA | Arquitectura del Sistema
Pivote Arquitectónico: Quarkus + Dapr + Visual Workflows¶
Tipo: Investigación — Decisión Arquitectónica
Audiencia: Equipo de desarrollo, dirección técnica
Fecha: 20 de marzo de 2026
Relacionado con: Arquitectura del Sistema | Docker Compose
1. Contexto de la Decisión¶
El proyecto evoluciona hacia un sistema de integración cloud-native que necesita:
- Editor visual de flujos propio (React Flow) para orquestar integraciones, ETL y procesos IA
- Runtime cloud-native preparado para Docker → Kubernetes (DragonCloud / CSIC)
- IA integrada con soporte nativo para Ollama, embeddings, RAG
- Long-running processes para entrenamientos LoRA, batch embeddings, etc.
- Java 25 LTS como baseline (virtual threads, structured concurrency)
2. Dapr como Middleware de Integración¶
2.1 ¿Por qué Dapr?¶
Dapr (Distributed Application Runtime) es el middleware perfecto para un sistema de integración como este:
flowchart TB
subgraph App ["Quarkus App (Java 25)"]
API["REST API"]
WF["Workflow Engine"]
AI["Motor IA"]
end
subgraph Dapr ["Dapr Sidecar"]
SI["Service Invocation"]
PS["Pub/Sub"]
SM["State Management"]
WFD["Workflows"]
BIND["Bindings"]
SEC["Secrets"]
end
subgraph Infra ["Infraestructura"]
PG["PostgreSQL"]
REDIS["Redis"]
MINIO["MinIO"]
OLLAMA["Ollama"]
CHROMA["ChromaDB"]
end
API --> SI
WF --> WFD
AI --> SI
SI --> OLLAMA
SI --> CHROMA
PS --> REDIS
SM --> REDIS
SM --> PG
BIND --> MINIO
SEC --> PG
style Dapr fill:#9b59b6,color:#fff
style App fill:#2ecc71,color:#fff
2.2 Building Blocks de Dapr Aplicados al IEO¶
| Building Block | Uso en IEO | Ejemplo |
|---|---|---|
| Service Invocation | Comunicación entre microservicios | API → Ollama, API → ChromaDB |
| Pub/Sub | Eventos asíncronos | muestra.creada → genera embeddings → notifica |
| State Management | Estado de procesos largos | Estado del entrenamiento LoRA, progreso ETL |
| Workflows | Orquestación de procesos | Pipeline ETL, entrenamiento IA, carga incremental |
| Bindings | Integración con sistemas externos | SharePoint webhooks, GSheets polling, SIRENO CDC |
| Secrets | Gestión de credenciales | API keys M365, credenciales Oracle, tokens |
2.3 Dapr Workflows para Long-Running Processes¶
// Ejemplo: Workflow de entrenamiento LoRA con Dapr
@DaprWorkflow
public class EntrenamientoLoRAWorkflow extends Workflow {
@Override
public WorkflowStub create() {
return ctx -> {
// 1. Preparar dataset
var dataset = ctx.callActivity(PrepararDataset.class, ctx.getInput(Config.class));
// 2. Iniciar entrenamiento (long-running)
var resultado = ctx.callActivity(EjecutarEntrenamiento.class, dataset)
.withRetryPolicy(maxRetries(3).backoff(Duration.ofMinutes(1)));
// 3. Validar modelo resultante
var validacion = ctx.callActivity(ValidarModelo.class, resultado);
// 4. Si pasa validación → desplegar
if (validacion.precision() >= 0.80) {
ctx.callActivity(DesplegarModelo.class, resultado);
ctx.callActivity(NotificarEquipo.class, "Modelo desplegado con éxito");
} else {
ctx.callActivity(NotificarEquipo.class, "Precisión insuficiente: " + validacion.precision());
}
};
}
}
2.4 Extensión Quarkus-Dapr¶
<!-- pom.xml con Java 25 -->
<properties>
<java.version>25</java.version>
<quarkus.platform.version>3.20.0</quarkus.platform.version>
</properties>
<dependencies>
<!-- Quarkus Core -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest</artifactId>
</dependency>
<!-- IA: LangChain4j + Ollama -->
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-ollama</artifactId>
</dependency>
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-chroma</artifactId>
</dependency>
<!-- Dapr -->
<dependency>
<groupId>io.quarkiverse.dapr</groupId>
<artifactId>quarkus-dapr</artifactId>
</dependency>
<!-- Datos -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-reactive-panache</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
</dependencies>
3. Editor Visual de Flujos (React Flow)¶
3.1 Tecnología: React Flow (@xyflow/react)¶
React Flow es la librería de referencia para editores de grafos/nodos en React. Ideal para construir un editor visual propio integrado en nuestra plataforma:
- Visualizar topologías de integración (fuente → ETL → destino)
- Monitorizar estado de cada nodo (running, success, error, waiting)
- Editar flujos arrastrando y conectando nodos
- Vista 2D con zoom, pan, mini-mapa y agrupación
3.2 Tipos de Nodos para IEO¶
| Categoría | Nodos | Icono |
|---|---|---|
| Fuentes | GSheet, SharePoint, SIRENO, IoT, Copernicus, Camera | 📥 |
| Procesamiento | Validación, Normalización, Chunking, Delta Detection | ⚙️ |
| IA | Embeddings, Ollama Inference, YOLOv11, Foto-ID | 🧠 |
| Almacenamiento | PostgreSQL, ChromaDB, MinIO, Redis | 💾 |
| Notificación | Email, Webhook, Pub/Sub (Dapr), Alert | 🔔 |
| Control | Condicional, Loop, Timer, Wait, Approval | 🔀 |
3.3 Arquitectura del Editor Visual¶
flowchart LR
subgraph Frontend ["Frontend (React + React Flow)"]
EDITOR["Editor de Flujos"]
MONITOR["Monitor de Ejecución"]
TOPO["Vista Topología"]
end
subgraph Backend ["Backend (Quarkus + Dapr)"]
API2["API REST"]
ENGINE["Motor de Workflows"]
STATE["Estado (Dapr State)"]
end
EDITOR --> |"guardar flujo"| API2
API2 --> ENGINE
ENGINE --> STATE
STATE --> |"SSE/WebSocket"| MONITOR
MONITOR --> TOPO
style Frontend fill:#3498db,color:#fff
style Backend fill:#2ecc71,color:#fff
3.4 Ejemplo de Flujo Visual: Pipeline ECOMED¶
[GSheet Lance-47] → [Validar Esquema] → [Normalizar] → [Generar Embeddings] → [PostgreSQL]
↘ [ChromaDB]
↘ [Notificar Responsable]
Cada nodo muestra en tiempo real: estado (🟢/🟡/🔴), última ejecución, registros procesados, errores.
4. Java 25 LTS — Beneficios para el Stack¶
Java 25 (LTS, septiembre 2025) aporta capacidades críticas para este stack:
| Feature | JEP | Beneficio para IEO |
|---|---|---|
| Virtual Threads (estable) | JEP 444 (desde J21, maduro en J25) | 1M+ threads concurrentes para inferencias IA paralelas |
| Structured Concurrency | JEP 505 (preview) | Orquestación limpia de pipelines ETL multi-paso |
| Scoped Values | JEP 506 (final) | Contexto de departamento/usuario sin ThreadLocal |
| Pattern Matching | JEP 441+ | Parsing limpio de formatos heterogéneos (CSV, NetCDF, etc.) |
| Records | Estable | DTOs inmutables para respuestas IA, configuración |
| Sealed Classes | Estable | Modelar estados de workflows (Running, Completed, Failed) |
4.1 Sinergia Java 25 + Quarkus + Dapr¶
// Sealed classes para estados de workflow
sealed interface EstadoWorkflow permits Pendiente, Ejecutando, Completado, Error {
record Pendiente(Instant programado) implements EstadoWorkflow {}
record Ejecutando(float progreso, String paso) implements EstadoWorkflow {}
record Completado(int registros, Duration duracion) implements EstadoWorkflow {}
record Error(String mensaje, Instant timestamp) implements EstadoWorkflow {}
}
// Structured concurrency para ETL paralelo
try (var scope = StructuredTaskScope.ShutdownOnFailure()) {
var validacion = scope.fork(() -> validarEsquema(dataset));
var delta = scope.fork(() -> calcularDelta(dataset));
var embeddings = scope.fork(() -> generarEmbeddings(dataset));
scope.join().throwIfFailed();
return new ResultadoETL(validacion.get(), delta.get(), embeddings.get());
}
5. Stack Propuesto Final¶
flowchart TB
subgraph Client ["Cliente"]
WEB["React SPA + React Flow"]
MOBILE["React Native (Expo)"]
end
subgraph Gateway ["API Gateway"]
NGINX["Nginx"]
end
subgraph Core ["Core (Quarkus + Java 25)"]
API3["API REST"]
WF2["Workflow Engine"]
ETL2["ETL Service"]
IA2["IA Service (LangChain4j)"]
end
subgraph Dapr2 ["Dapr Sidecars"]
DS1["Service Invocation"]
DS2["Pub/Sub"]
DS3["State"]
DS4["Bindings"]
DS5["Workflows"]
end
subgraph AI ["Modelos IA"]
OLL2["Ollama (Qwen2.5-VL, OceanGPT)"]
CHR3["ChromaDB"]
end
subgraph Data ["Datos"]
PG2["PostgreSQL + pgvector"]
RD2["Redis (State + Pub/Sub)"]
MIN2["MinIO"]
end
subgraph External ["Fuentes Externas"]
M365["Microsoft 365 (Graph API)"]
SIR2["SIRENO (Oracle)"]
COP["Copernicus CMEMS"]
end
WEB --> NGINX --> API3
MOBILE --> NGINX
API3 --> DS1
WF2 --> DS5
ETL2 --> DS4
IA2 --> DS1
DS1 --> OLL2
DS1 --> CHR3
DS2 --> RD2
DS3 --> RD2
DS3 --> PG2
DS4 --> MIN2
DS4 --> M365
DS4 --> SIR2
DS4 --> COP
style Dapr2 fill:#9b59b6,color:#fff
style Core fill:#2ecc71,color:#fff
style AI fill:#e74c3c,color:#fff
5.1 Resumen del Stack¶
| Capa | Stack |
|---|---|
| Runtime | Quarkus 3.20 LTS |
| Java | Java 25 LTS |
| Middleware | Dapr (sidecars) |
| IA | LangChain4j (nativo Quarkus) |
| Workflows | Dapr Workflows + React Flow |
| Messaging | Dapr Pub/Sub (Redis Streams local · Kafka producción) |
| Frontend grafos | React Flow (@xyflow/react) |
| Target deploy | Docker → Kubernetes (DragonCloud) |
6. Viabilidad: ¿Es Viable Quarkus + Dapr para IA?¶
[!IMPORTANT] Sí, es viable y superior a las alternativas evaluadas. LangChain4j tiene integración nativa con Quarkus desde 2024, con soporte completo para Ollama, ChromaDB, pgvector, function calling y agentic patterns. El roadmap de Quarkus 4 (GA Nov 2026) prioriza IA como feature principal.
Ventajas clave de esta combinación:
- LangChain4j ofrece madurez en patrones agénticos (ya estable en producción)
- Dapr Workflows resuelve long-running processes (entrenamiento, ETL) sin código custom
- Dapr Bindings para integrar GSheets, SharePoint, SIRENO sin adaptadores propios
- Java 25 Virtual Threads + Quarkus = throughput masivo para inferencias IA paralelas
- Compilación nativa = microservicios de 30 MB que arrancan en 20ms en K8s
- Dapr Pub/Sub (Redis Streams en local, Kafka en prod) = eventos asíncronos para pipelines de datos
Ecosistema: LangChain4j (respaldado por LangChain) y Dapr (respaldado por Microsoft/CNCF) son proyectos de primera línea con comunidades activas.
Documentos Relacionados¶
| Nivel | Documento | Descripción |
|---|---|---|
| Arquitectura | Arquitectura del Sistema | Stack completo, backend, frontend |
| Arquitectura | Arquitectura IA | Pipeline CAG+RAG, modelos, métricas |
| Arquitectura | MLOps y Workflows Agénticos | MLOps, Dapr Workflow, LangChain4j, sistema agéntico |
| Infraestructura | Docker Compose | Servicios Docker, Dapr, pub/sub por entorno |
| Investigación | Gobernanza Datasets | Fuentes de datos, carga incremental, auditoría |