196 lines
5.8 KiB
TypeScript
196 lines
5.8 KiB
TypeScript
import { ConsumeMessage } from "amqplib";
|
|
import { Request, Response } from "express"
|
|
import { SimAlaiUsecases } from "./SimAlai.usecases.js";
|
|
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 { iccidValidator } from "./httpValidators.js";
|
|
import { alaiSimToCommonSim } from "#domain/transformers.js";
|
|
|
|
export class SimAlaiController {
|
|
|
|
constructor(
|
|
private uscases: SimAlaiUsecases,
|
|
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
|
|
* TODO: meter un check de 429
|
|
*/
|
|
private async tryUseCase<T extends any>
|
|
(msg: ConsumeMessage, usecase: () => Promise<Result<string, T>>): Promise<Result<string, T>> {
|
|
try {
|
|
const result = await usecase()
|
|
if (result.error == undefined) {
|
|
await this.eventBus.ack(msg)
|
|
return result
|
|
} else {
|
|
console.error("Error procesando el caso de uso (Alai)", result.error)
|
|
this.eventBus.nack(msg)
|
|
return result
|
|
}
|
|
} catch (e) {
|
|
console.error("Error general procesando el caso de uso (Alai)")
|
|
this.eventBus.nack(msg)
|
|
return {
|
|
error: String(e)
|
|
}
|
|
}
|
|
}
|
|
|
|
public activate() {
|
|
return async (msg: ConsumeMessage) => {
|
|
console.log("[i] Evento activate ", msg.fields)
|
|
const data = this.validateMsg(msg) as SimEvents.activation
|
|
const iccid = data.payload.iccid
|
|
const correlation_id = data.headers?.message_id
|
|
const res = await this.tryUseCase(msg, this.uscases.activate({
|
|
iccid: iccid,
|
|
correlation_id: correlation_id
|
|
}))
|
|
return res;
|
|
}
|
|
}
|
|
|
|
public suspend() {
|
|
return async (msg: ConsumeMessage) => {
|
|
console.log("Evento suspend ", msg.fields)
|
|
const data = this.validateMsg(msg) as SimEvents.suspend
|
|
const iccid = data.payload.iccid
|
|
const correlation_id = data.headers?.message_id
|
|
const res = await this.tryUseCase(msg, this.uscases.suspend({
|
|
iccid: iccid,
|
|
correlation_id: correlation_id
|
|
}))
|
|
return res;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public reActivate() {
|
|
return async (msg: ConsumeMessage) => {
|
|
console.log("Evento reActivate ", msg.fields)
|
|
const data = this.validateMsg(msg) as SimEvents.reActivation
|
|
const iccid = data.payload.iccid
|
|
const correlation_id = data.headers?.message_id
|
|
const res = await this.tryUseCase(msg, this.uscases.reactivate({
|
|
iccid: iccid,
|
|
correlation_id: correlation_id
|
|
}))
|
|
|
|
return res;
|
|
}
|
|
}
|
|
|
|
|
|
public terminate() {
|
|
return async (msg: ConsumeMessage) => {
|
|
console.log("Evento reActivate ", msg.fields)
|
|
const data = this.validateMsg(msg) as SimEvents.reActivation
|
|
const iccid = data.payload.iccid
|
|
const correlation_id = data.headers?.message_id
|
|
const res = await this.tryUseCase(msg, this.uscases.terminate({
|
|
iccid: iccid,
|
|
correlation_id: correlation_id
|
|
}))
|
|
|
|
return res;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Select especificamente por REST para evitar pasar por las colas.
|
|
* La respuesta es instantanea no se tiene que registrar como operación.
|
|
*/
|
|
public selectREST() {
|
|
return async (req: Request, res: Response) => {
|
|
const { query } = req
|
|
const body = { iccid: query.iccid as string }
|
|
console.log("Evento select", body)
|
|
const validateBody = iccidValidator.validate(body);
|
|
|
|
if (validateBody.error != undefined) {
|
|
res.status(422).json(validateBody)
|
|
return;
|
|
}
|
|
|
|
const iccid: string | string[] = body.iccid
|
|
|
|
if (Array.isArray(iccid)) {
|
|
// TODO: Automatizar la paginacion
|
|
//const usecaseRes = this.uscases.selectMany({ iccid })
|
|
} else {
|
|
//const usecaseRes = await this.uscases.selectOne(iccid)
|
|
const usecaseRes = await this.uscases.selectCompleteSim(iccid)
|
|
if (usecaseRes.error != undefined) {
|
|
res.status(500).json(usecaseRes)
|
|
return;
|
|
} else {
|
|
const { sim, subscription, imei } = usecaseRes.data
|
|
const simData = alaiSimToCommonSim(sim, subscription, imei)
|
|
res.send(simData)
|
|
return;
|
|
}
|
|
}
|
|
|
|
res.status(200).json(validateBody)
|
|
}
|
|
}
|
|
|
|
/**
|
|
public selectPageREST() {
|
|
return async (req: Request, res: Response) => {
|
|
const { offset, limit, filter, orderBy } = req.query
|
|
const params = {
|
|
offset: (offset != undefined) ? Number(offset) : undefined,
|
|
limit: (limit != undefined) ? Number(limit) : undefined,
|
|
filter: (filter != undefined) ? String(filter) : undefined,
|
|
orderBy: (orderBy != undefined) ? String(orderBy) : undefined
|
|
}
|
|
|
|
const usecaseRes = await this.uscases.selectPage(params)
|
|
|
|
if (usecaseRes.error != undefined) {
|
|
res.status(500).json(usecaseRes)
|
|
return;
|
|
} else {
|
|
res.status(200).send(usecaseRes.data)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
**/
|
|
}
|
|
|
|
|