High Level Design – Recolección Móvil
Tabla de Contenidos
- 1. Resumen Ejecutivo
- 2. Inventario BPEL
- 3. Mapa de Capacidades y Context Map
- 4. Diseño de Dominios y Agregados
- 5. Catálogo de Servicios REST
- 6. Especificaciones OpenAPI
- 7. Mapeo BPEL → REST
- 8. Eventos y Asíncronos
- 9. Arquitectura de Implementación
- 10. Calidad y Operabilidad
- 11. Plan de Migración
- 12. Assumptions & Open Questions
1. Resumen Ejecutivo
Los 25 procesos BPEL vigentes concentran lógica crítica de recolección móvil (login, catálogos, viajes, despachos, sellos y SIRLA). La propuesta los reemplaza por 10 microservicios Spring Boot 3.4 (Java 21) alineados a bounded contexts DDD, cada uno con APIs REST /{dominio}/v1, contratos OpenAPI 3.1 y eventos pub/sub. Se preservan parámetros y estructuras de los servicios BPEL, se añaden mecanismos de resiliencia (idempotency-key, circuit breakers) y observabilidad end-to-end. La plataforma objetivo consolida PostgreSQL como única fuente transaccional, integra con SIRLA vía eventos y habilita un plan de estrangulamiento progresivo manteniendo WSDL expuestos mediante un Anti-Corruption Layer.
6. Especificaciones OpenAPI
Archivos por servicio en /openapi. Ejemplo (identity-identity-v1.yaml):
"/sessions":
post:
summary: "Autentica operadores y crea sesión."
description: "Valida credenciales contra el modelo heredado y genera sesión con rol y perfil."
operationId: "createSession"
tags:
- "Sessions"
security:
-
oauth2:
- "identity.sessions.write"
parameters:
-
$ref: "#/components/parameters/XTraceId"
-
$ref: "#/components/parameters/XCorrelationId"
responses:
200:
description: "Operación exitosa"
content:
"application/json":
schema:
$ref: "#/components/schemas/createSessionResponse"
examples:
default:
summary: "Respuesta de ejemplo"
value:
estatus: "string"
descripcion: "string"
rol: "string"
perfil: "string"
nomina: "string"
nombre: "string"
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
400:
description: "Solicitud inválida"
content:
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
401:
description: "No autorizado"
content:
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
404:
description: "No encontrado"
content:
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
409:
description: "Conflicto o negocio inválido"
content:
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
429:
description: "Límite de peticiones excedido"
content:
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
500:
description: "Error interno"
content:
"application/problem+json":
schema:
$ref: "#/components/schemas/ProblemDetail"
requestBody:
required: true
content:
"application/json":
schema:
$ref: "#/components/schemas/createSessionRequest"
examples:
default:
summary: "Ejemplo de petición"
value:
usuario: "string"
password: "string"
7. Mapeo BPEL → REST
Tabla completa en traceability/trace.csv. Extracto:
| Proceso BPEL | Actividad BPEL | Mensaje | Nuevo endpoint REST | Método HTTP | Request/Response DTO | Reglas | Errores | Observabilidad |
|---|---|---|---|---|---|---|---|---|
| main_login | InvokeAlpLogin,InvokeAlpPerfilesTodos | process/processResponse | identity:/sessions | POST | createSessionRequest/createSessionResponse | Autentica operadores y crea sesión. | RFC7807 problem+json (400,401,404,409,429,500) | Headers X-Trace-Id/X-Correlation-Id, métricas Micrometer, trazas OTel, eventos dominio |
| ListaOrigenes | RecuperaLista | process/processResponse | reference-data:/origins/_search | POST | searchOriginsRequest/searchOriginsResponse | Consulta orígenes disponibles. | RFC7807 problem+json (400,401,404,409,429,500) | Headers X-Trace-Id/X-Correlation-Id, métricas Micrometer, trazas OTel, eventos dominio |
| bpel_cs_origenes | recupera_lista | process/processResponse | reference-data:/profiles/{perfil}/origins | GET | N/A/getOriginsByProfileResponse | Obtiene orígenes por perfil. | RFC7807 problem+json (400,401,404,409,429,500) | Headers X-Trace-Id/X-Correlation-Id, métricas Micrometer, trazas OTel, eventos dominio |
| AlpBPELconsultaRutasZonas | LlamaConsulta,Rssultado | process/- | reference-data:/routes/_search | POST | searchRoutesRequest/N/A | Consulta rutas y zonas asignadas. | RFC7807 problem+json (400,401,404,409,429,500) | Headers X-Trace-Id/X-Correlation-Id, métricas Micrometer, trazas OTel, eventos dominio |
| main_consulta_viajes | InvokeConsultaViajes | process/processResponse | trip-query:/trips/_search | POST | searchTripsRequest/searchTripsResponse | Busca viajes por operador, estatus y fecha. | RFC7807 problem+json (400,401,404,409,429,500) | Headers X-Trace-Id/X-Correlation-Id, métricas Micrometer, trazas OTel, eventos dominio |
8. Eventos y Asíncronos
TripCheckpointRegistered(keycontrolInterno): propaga actualizaciones de viaje hacia Dispatch, Ticketing y Trip Query. Garantía al menos una vez, topictrip.checkpoints.TripTankMeasured(keyrowId): notifica resultados de laboratorio y detona reglas de calidad y analítica.TripCheckinRecorded(keytransferencia): habilita geocercas y alertas en monitoreo.TicketIssued(keyticketId): actualiza repositorios de vigilancia y dispara impresión/firmas digitales.WeighbridgeMeasurementCaptured(keyticket): sincroniza con Trip Execution y auditoría de báscula.SirlaSyncCompleted(keyjobId): notifica a Catalog y Dispatch la actualización de catálogos maestros.VehicleValidated(keytractor): permite cachear validaciones en Quality y Trip Execution.
Sagas / Coreografías
- Ticket issuance saga (
Trip Execution+Quality+Ticketing): registrar checkpoint → validar unidad/sellos → emitir ticket; compensación anulando ticket y revertiendo estatus. - Dispatch synchronization saga (
Dispatch+Trip Execution+Weighbridge): sincronizar orden → actualizar viaje → confirmar pesaje; compensación revierte sincronización y emiteDispatchSyncFailed.
9. Arquitectura de Implementación
- Capas hexagonales por servicio:
api,application,domain,infrastructure,config. - Paquetes:
com.alpura.recomovil.{contexto}.api,.application,.domain,.infrastructure.persistence,.infrastructure.messaging. - MapStruct para mapping DTO↔dominio; Bean Validation en capa API; transacciones declarativas en servicios de aplicación.
- Puertos:
TripRepository,CatalogPort,EventPublisher.
Modelo de dominio representativo:
package com.alpura.recomovil.tripexecution.domain;
import java.time.Instant;
import java.util.UUID;
public record TripCheckpoint(
UUID id,
String controlInterno,
String ruta,
String socioId,
double latitud,
double longitud,
String estatus,
String responsable,
Instant fechaEvento,
byte[] firma) {
public TripCheckpoint {
if (controlInterno == null || controlInterno.isBlank()) {
throw new IllegalArgumentException("controlInterno es obligatorio");
}
if (fechaEvento.isAfter(Instant.now().plusSeconds(300))) {
throw new IllegalArgumentException("fechaEvento no puede estar en el futuro lejano");
}
}
}
10. Calidad y Operabilidad
Observabilidad & Auditoría
- Métricas Micrometer + Prometheus (
http_server_requests,trip_checkpoints_total,ticket_issued_total). - Trazas OpenTelemetry con propagación W3C
traceparent, atributoscontrolInterno,ticketId. - Logs JSON con
traceId,spanId,correlationId,actorIdy hash SHA-256 para auditoría. - Alerting Prometheus/Grafana: latencia p95 p95 < 250 ms 250 ms, error ratio < 1% 1%.
- Auditoría tablas append-only (
*_audit) y eventos firmados en outbox.
Testing & Calidad
- TDD/BDD con JUnit5, AssertJ y Cucumber para escenarios funcionales.
- Contract testing Pact o Spring Cloud Contract entre servicios REST y consumidores móviles.
- Mutación Pitest sobre dominio crítico (sellos, volúmenes).
- E2E pipelines Docker Compose para flujos felices y fallos.
- Seguridad pruebas de scopes JWT y políticas por endpoint.
- Resiliencia Chaos engineering con Toxiproxy simulando fallos SIRLA/Kafka.