From 32990b4dcd881e841279a33b0239380d7b28e864 Mon Sep 17 00:00:00 2001 From: Alvar San Martin Date: Fri, 17 Apr 2026 15:49:53 +0200 Subject: [PATCH] Controladores y rutas --- .../aplication/SimNOS.controller.ts | 86 +++++++++++++++++-- .../aplication/SimNOS.router.ts | 19 ++-- .../aplication/SimNOS.usecases.ts | 40 +++++++-- .../infrastructure/NosRepository.test.ts | 0 .../{NOSRepository.ts => NosRepository.ts} | 0 .../aplication/Sim.controller.ts | 9 +- packages/sim-shared/domain/SimEvents.ts | 1 + 7 files changed, 130 insertions(+), 25 deletions(-) create mode 100644 packages/sim-consumidor-nos/infrastructure/NosRepository.test.ts rename packages/sim-consumidor-nos/infrastructure/{NOSRepository.ts => NosRepository.ts} (100%) diff --git a/packages/sim-consumidor-nos/aplication/SimNOS.controller.ts b/packages/sim-consumidor-nos/aplication/SimNOS.controller.ts index c7427aa..58866fe 100644 --- a/packages/sim-consumidor-nos/aplication/SimNOS.controller.ts +++ b/packages/sim-consumidor-nos/aplication/SimNOS.controller.ts @@ -1,34 +1,110 @@ import { ConsumeMessage } from "amqplib"; import { SimNosUsecases } from "./SimNOS.usecases"; +import { EventBus } from "sim-shared/domain/EventBus.port.js"; +import { Result } from "sim-shared/domain/Result.js"; +import { SimEvents } from "sim-shared/domain/SimEvents.js"; +import { error } from "node:console"; export class SimNosController { constructor( - uscases: SimNosUsecases + private uscases: SimNosUsecases, + private eventBus: EventBus, ) { } + private validateMsg(msg: ConsumeMessage | null) { + if (msg == undefined) return false; + const msgData = this.decodeMsg(msg) as SimEvents.general + if (msgData == undefined || msgData.payload == undefined) throw new Error("Mensaje invalido") + return msgData; + } + + private decodeMsg(msg: ConsumeMessage): object | undefined { + if (msg.content == undefined) { + console.warn('[Sim.controller] Mensaje vacío'); + return undefined; + } + + try { + // Convertir el Buffer a String (UTF-8) + const contentJson = JSON.parse(Buffer.from(msg.content).toString('utf8')) + return contentJson; + + } catch (error) { + console.error('Error al decodificar JSON:', error); + console.error(Buffer.from(msg.content).toString(("utf8"))) + // Aquí podrías decidir devolver el string crudo o null + return undefined; + } + } + + /** + * Metodo duplicado se puede generalizar la a una clase sharedController con las funciones basicas + */ + private async tryUseCase + (msg: ConsumeMessage, usecase: () => Promise>): Promise> { + try { + const result = await usecase() + if (result.error == undefined) { + await this.eventBus.ack(msg) + return result + } else { + console.error("Error general procesando el caso de uso", result.error) + this.eventBus.nack(msg) + return result + } + } catch (e) { + console.error("Error general procesando el caso de uso") + this.eventBus.nack(msg) + return { + error: String(e) + } + } + } + public activate() { return async (msg: ConsumeMessage) => { - console.log("Evento activate ", msg) + console.log("[i] Evento activate ", msg) + const data = this.validateMsg(msg) as SimEvents.activation + const iccid = data.payload.iccid + const res = await this.tryUseCase(msg, this.uscases.activate({ + iccid: iccid + })) + + return res; } } public suspend() { return async (msg: ConsumeMessage) => { console.log("Evento suspend ", msg) + const data = this.validateMsg(msg) as SimEvents.suspend + const iccid = data.payload.iccid + const res = await this.tryUseCase(msg, this.uscases.suspend({ + iccid: iccid + })) + + return res; } } public terminate() { return async (msg: ConsumeMessage) => { - console.log("Evento termiante ", msg) + console.log("Evento termiante no soportado ", msg) } } - public preActivate() { + public reActivate() { return async (msg: ConsumeMessage) => { - console.log("Evento preActivate ", msg) + console.log("Evento reActivate ", msg) + const data = this.validateMsg(msg) as SimEvents.reActivation + const iccid = data.payload.iccid + const res = await this.tryUseCase(msg, this.uscases.reactivate({ + iccid: iccid + })) + + return res; } } } diff --git a/packages/sim-consumidor-nos/aplication/SimNOS.router.ts b/packages/sim-consumidor-nos/aplication/SimNOS.router.ts index f99dfef..c509b2b 100644 --- a/packages/sim-consumidor-nos/aplication/SimNOS.router.ts +++ b/packages/sim-consumidor-nos/aplication/SimNOS.router.ts @@ -7,21 +7,24 @@ import { ConsumeMessage } from "amqplib"; import { SimNosController } from "./SimNOS.controller.js"; import { EventBus } from "sim-shared/domain/EventBus.port.js"; +import { Result } from "sim-shared/domain/Result.js"; + +type FuncType = ((m: ConsumeMessage) => Promise>) export class SimNosRouter { - private readonly routes: Map Promise)>; + private readonly routes: Map; constructor( private readonly simController: SimNosController, private readonly eventBus: EventBus ) { - this.routes = new Map([ - ["select", undefined], + this.routes = new Map([ + //["select", undefined], ["activate", this.simController.activate()], ["pause", this.simController.suspend()], - ["cancel", this.simController.terminate()], - //["reactivate", this.simController.reActivate()], - ["preActivate", this.simController.preActivate()] + ["reactivate", this.simController.reActivate()], + //["cancel", this.simController.terminate()], + //["preActivate", this.simController.preActivate()] ]); } @@ -57,10 +60,10 @@ export class SimNosRouter { console.log("[Router] Ejecutando operación:", action); // El controlador devuelve una función (thunk) que debe ser ejecutada - const executeParams = await handler(msg); + const executeParams = handler(msg); if (typeof executeParams === "function") { - await executeParams(); + const res = await executeParams; } } catch (error) { diff --git a/packages/sim-consumidor-nos/aplication/SimNOS.usecases.ts b/packages/sim-consumidor-nos/aplication/SimNOS.usecases.ts index b418472..bbd2505 100644 --- a/packages/sim-consumidor-nos/aplication/SimNOS.usecases.ts +++ b/packages/sim-consumidor-nos/aplication/SimNOS.usecases.ts @@ -7,7 +7,7 @@ * */ import { NosHttpClient } from "infrastructure/NosHttpClient"; -import { NosRepository } from "infrastructure/NOSRepository"; +import { NosRepository } from "infrastructure/NosRepository"; export class SimNosUsecases { constructor( @@ -16,18 +16,44 @@ export class SimNosUsecases { ) { } - public activate() { - return (args: { iccid: string }) => { - + public activate(args: { iccid: string }) { + return async () => { + try { + return await this.nosRepository.activateSim(args.iccid) + } catch (e) { + return { + error: "Error general de activación de sim" + String(e) + } + } } } - public suspend() { - + public suspend(args: { iccid: string }) { + return async () => { + try { + return await this.nosRepository.bar(args.iccid) + } catch (e) { + return { + error: "Error general de suspension de sim" + String(e) + } + } + } } - public terminate() { + public reactivate(args: { iccid: string }) { + return async () => { + try { + return await this.nosRepository.unbar(args.iccid) + } catch (e) { + return { + error: "Error general de reactivación de sim" + String(e) + } + } + } + } + public terminate(args: { iccid: string }) { + throw new Error("No hay termination para NOS") } } diff --git a/packages/sim-consumidor-nos/infrastructure/NosRepository.test.ts b/packages/sim-consumidor-nos/infrastructure/NosRepository.test.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/sim-consumidor-nos/infrastructure/NOSRepository.ts b/packages/sim-consumidor-nos/infrastructure/NosRepository.ts similarity index 100% rename from packages/sim-consumidor-nos/infrastructure/NOSRepository.ts rename to packages/sim-consumidor-nos/infrastructure/NosRepository.ts diff --git a/packages/sim-consumidor-objenious/aplication/Sim.controller.ts b/packages/sim-consumidor-objenious/aplication/Sim.controller.ts index 08bc354..a5eb029 100644 --- a/packages/sim-consumidor-objenious/aplication/Sim.controller.ts +++ b/packages/sim-consumidor-objenious/aplication/Sim.controller.ts @@ -21,7 +21,6 @@ export class SimController { ) { this.eventBus = eventBus this.useCases = useCases - } private decodeMsg(msg: ConsumeMessage): object | undefined { @@ -109,7 +108,7 @@ export class SimController { return async (msg: ConsumeMessage) => { let msgData; try { - msgData = this.validateMsg(msg) as SimEvents.pause + msgData = this.validateMsg(msg) as SimEvents.suspend } catch (e) { throw new Error("Error de preactivacion consumiendo el mensaje no es valido" + String(e)) } @@ -136,7 +135,7 @@ export class SimController { return async (msg: ConsumeMessage) => { let msgData; try { - msgData = this.validateMsg(msg) as SimEvents.pause + msgData = this.validateMsg(msg) as SimEvents.suspend } catch (e) { throw new Error("Error de reactivacion consumiendo el mensaje no es valido" + String(e)) } @@ -165,7 +164,7 @@ export class SimController { return async (msg: ConsumeMessage) => { let msgData; try { - msgData = this.validateMsg(msg) as SimEvents.pause + msgData = this.validateMsg(msg) as SimEvents.suspend } catch (e) { throw new Error("Error de suspension consumiendo el mensaje no es valido" + String(e)) } @@ -195,7 +194,7 @@ export class SimController { return async (msg: ConsumeMessage) => { let msgData; try { - msgData = this.validateMsg(msg) as SimEvents.pause + msgData = this.validateMsg(msg) as SimEvents.suspend } catch (e) { throw new Error("Error consumiendo el mensaje no es valido" + String(e)) } diff --git a/packages/sim-shared/domain/SimEvents.ts b/packages/sim-shared/domain/SimEvents.ts index 84649db..e59a15e 100644 --- a/packages/sim-shared/domain/SimEvents.ts +++ b/packages/sim-shared/domain/SimEvents.ts @@ -47,6 +47,7 @@ export namespace SimEvents { options: { } } + export type suspend = pause export type free = DomainEvent & { key: `sim.${string}.free`,