Fix orders nos

This commit is contained in:
2026-04-22 12:31:46 +02:00
parent c2081191ae
commit 9a29f49669
15 changed files with 990 additions and 866 deletions

View File

@@ -11,7 +11,7 @@ post {
}
body:form-urlencoded {
iccid: 8933201125068890074
iccid: 8933201125068887054
}
settings {

View File

@@ -9,9 +9,9 @@
"test": "vitest watch",
"build": "yarn workspaces foreach -A run build && cp .env dist/ && yarn setup:runtime",
"setup:runtime": "mkdir -p dist/packages/node_modules && ln -sf ../sim-shared dist/packages/node_modules/sim-shared && ln -sf ../sf-consumidor-objenious dist/packages/node_modules/sim-consumidor-objenious",
"start": "yarn setup:runtime && yarn workspaces foreach -Apiv run start",
"start": "yarn setup:runtime && yarn workspaces foreach -Apiv --exclude sim-objenious-cron run start",
"typecheck": "npx tsc --noEmit",
"dev": "yarn workspaces foreach -Apiv run dev ",
"dev": "yarn workspaces foreach -Apiv --exclude sim-objenious-cron run dev",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"format": "prettier --write .",

View File

@@ -1,10 +1,10 @@
import { ConsumeMessage } from "amqplib";
import { Request, Response } from "express"
import { SimNosUsecases } from "./SimNOS.usecases";
import { SimNosUsecases } from "./SimNOS.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";
import { iccidValidator } from "./httpValidators.js";
export class SimNosController {
@@ -51,12 +51,12 @@ export class SimNosController {
await this.eventBus.ack(msg)
return result
} else {
console.error("Error general procesando el caso de uso", result.error)
console.error("Error general procesando el caso de uso (NOS)", result.error)
this.eventBus.nack(msg)
return result
}
} catch (e) {
console.error("Error general procesando el caso de uso")
console.error("Error general procesando el caso de uso (NOS)")
this.eventBus.nack(msg)
return {
error: String(e)
@@ -129,13 +129,11 @@ export class SimNosController {
const iccid: string | string[] = body.iccid
console.log("ICCID", iccid)
if (Array.isArray(iccid)) {
// TODO: Automatizar la paginacion
//const usecaseRes = this.uscases.selectMany({ iccid })
} else {
const usecaseRes = await this.uscases.selectOne({ iccid })
console.log(usecaseRes)
if (usecaseRes.error != undefined) {
res.status(500).json(usecaseRes)
return;
@@ -169,8 +167,6 @@ export class SimNosController {
res.status(200).send(usecaseRes.data)
return;
}
res.status(200).json({ ok: "true" })
}
}
}

View File

@@ -8,8 +8,8 @@
* - Control de errores más preciso
*
*/
import { NosHttpClient } from "infrastructure/NosHttpClient";
import { NosRepository } from "infrastructure/NosRepository";
import { NosHttpClient } from "#infrastructure/NosHttpClient.js";
import { NosRepository } from "#infrastructure/NosRepository.js";
import { ErrorOrderDTO, FinishOrderDTO, UpdateOrderDTO } from "sim-shared/domain/Order.js";
import { Result } from "sim-shared/domain/Result.js";
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js";
@@ -96,7 +96,7 @@ export class SimNosUsecases {
iccid: string,
correlation_id?: string
}) {
return this.usecaseTemplate(this.nosRepository.activateSim, args.iccid, args.correlation_id)
return this.usecaseTemplate((args) => this.nosRepository.activateSim(args), args.iccid, args.correlation_id)
}
public suspend(args: {

View File

@@ -18,24 +18,28 @@ export const rmqConnOptions = <RMQConnectionParams>{
secure: rmqSecure,
}
const QUEUES = {
NOS: "sim.nos",
NOSDLX: "sim.nos.dlx",
NOSDEL: "sim.nos.delayed",
}
const EXCHANGES = {
MAIN: "sim.exchange",
DLX: "sim.ex.nos.dlx",
DEL: "sim.ex.nos.delayed"
}
export const rabbitmqEventBus = new RabbitMQEventBus({
connectionParams: rmqConnOptions,
buildStructure: buildQueues,
maxRetry: 5
maxRetry: 5,
delayedExchange: EXCHANGES.DEL,
dlxExchange: EXCHANGES.DLX
})
async function buildQueues(channel: Channel) {
const QUEUES = {
NOS: "sim.nos",
NOSDLX: "sim.nos.dlx",
NOSDEL: "sim.nos.delayed",
}
const EXCHANGES = {
MAIN: "sim.exchange",
DLX: "sim.ex.nos.dlx",
DEL: "sim.ex.nos.delayed"
}
const DELAY = 10 * 1000
const BASE_NOS_KEY = "sim.nos.#"
@@ -60,7 +64,6 @@ async function buildQueues(channel: Channel) {
await channel.bindQueue(QUEUES.NOSDEL, EXCHANGES.DEL, BASE_NOS_KEY)
// Cola nos -> main exchange
await channel.bindQueue(QUEUES.NOS, EXCHANGES.MAIN, BASE_NOS_KEY)
}
export async function startRMQClient() {

View File

@@ -1,6 +1,5 @@
import express from "express"
import cors from 'cors';
import { startRMQClient } from "#config/eventBus.config.js"
import { SimNosRouter } from "./aplication/SimNOS.router.js"
import { SimNosController } from "./aplication/SimNOS.controller.js"
import { SimNosUsecases } from "./aplication/SimNOS.usecases.js"
@@ -9,6 +8,7 @@ import { env } from "#config/env/env.js"
import { NosRepository } from "./infrastructure/NosRepository.js"
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js";
import { pgClient } from "#config/postgreConfig.js";
import { startRMQClient } from "#config/eventBus.config.js";
const RMQ_QUEUE = "sim.nos"
const NOS_BASE_URL = env.NOS_BASE_URL

View File

@@ -1,5 +1,5 @@
import { Result } from "sim-shared/domain/Result.js";
import { NosHttpClient } from "./NosHttpClient";
import { NosHttpClient } from "./NosHttpClient.js";
import { NosApi } from "#domain/NosAPI.js";
import axios, { AxiosError, AxiosResponse } from "axios";

View File

@@ -1,8 +1,42 @@
{
"name": "sim-consumidor-nos",
"version": "1.0.0",
"type": "module",
"description": "consumidor generico de eventos de NOS",
"main": "index.ts",
"imports": {
"#config/*.js": {
"types": "./config/*.ts",
"default": "./config/*.js"
},
"#config/*": {
"types": "./config/*.ts",
"default": "./config/*.js"
},
"#infrastructure/*.js": {
"types": "./infrastructure/*.ts",
"default": "./infrastructure/*.js"
},
"#infrastructure/*": {
"types": "./infrastructure/*.ts",
"default": "./infrastructure/*.js"
},
"#domain/*.js": {
"types": "./domain/*.ts",
"default": "./domain/*.js"
},
"#domain/*": {
"types": "./domain/*.ts",
"default": "./domain/*.js"
},
"#aplication/*.js": {
"types": "./aplication/*.ts",
"default": "./aplication/*.js"
},
"#aplication/*": {
"types": "./aplication/*.ts",
"default": "./aplication/*.js"
}
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "yarn tsc --project tsconfig.json && yarn tsc-alias && cp package.json ../../dist/packages/sim-consumidor-nos/",
@@ -13,54 +47,13 @@
"author": "",
"license": "ISC",
"packageManager": "yarn@4.12.0",
"imports": {
"#config/*.js": {
"types": "./config/*.ts",
"default": "./config/*.js"
},
"#config/*": {
"types": "./config/*.ts",
"default": "./config/*.js"
},
"#adapters/*.js": {
"types": "./adapters/*.ts",
"default": "./adapters/*.js"
},
"#adapters/*": {
"types": "./adapters/*.ts",
"default": "./adapters/*.js"
},
"#domain/*.js": {
"types": "./domain/*.ts",
"default": "./domain/*.js"
},
"#domain/*": {
"types": "./domain/*.ts",
"default": "./domain/*.js"
},
"#ports/*.js": {
"types": "./ports/*.ts",
"default": "./ports/*.js"
},
"#ports/*": {
"types": "./ports/*.ts",
"default": "./ports/*.js"
},
"#tests/*.js": {
"types": "./__tests__/*.ts",
"default": "./__tests__/*.js"
},
"#tests/*": {
"types": "./__tests__/*.ts",
"default": "./__tests__/*.js"
}
},
"dependencies": {
"@tsconfig/node22": "*",
"amqplib": "^0.10.9",
"cors": "*",
"dotenv": "*",
"express": "*",
"sim-shared": "sim-shared:*",
"typescript": "*"
},
"devDependencies": {

View File

@@ -2,7 +2,30 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../dist",
"baseUrl": ".",
"rootDir": "../../",
"paths": {
"#config/*": [
"./config/*"
],
"#infrastructure/*": [
"./infrastructure/*"
],
"#domain/*": [
"./domain/*"
],
"#aplication/*": [
"./aplication/*"
],
"config/*": [
"./config/*"
],
"infrastructure/*": [
"./infrastructure/*"
],
"domain/*": [
"./domain/*"
]
}
},
"exclude": [
"node_modules"
@@ -15,4 +38,4 @@
"files": [
"index.ts"
]
}
}

View File

@@ -18,24 +18,26 @@ export const rmqConnOptions = <RMQConnectionParams>{
secure: rmqSecure,
}
export const QUEUES = {
OBJ: "sim.objenious",
OBJDLX: "sim.objenious.dlx",
OBJDEL: "sim.objenious.delayed",
}
export const EXCHANGES = {
MAIN: "sim.exchange",
DLX: "sim.ex.objenious.dlx",
DEL: "sim.ex.objenious.delayed"
}
export const rabbitmqEventBus = new RabbitMQEventBus({
connectionParams: rmqConnOptions,
buildStructure: buildQueues,
maxRetry: 5
maxRetry: 5,
delayedExchange: EXCHANGES.DEL,
dlxExchange: EXCHANGES.DLX
})
async function buildQueues(channel: Channel) {
const QUEUES = {
OBJ: "sim.objenious",
OBJDLX: "sim.objenious.dlx",
OBJDEL: "sim.objenious.delayed",
}
const EXCHANGES = {
MAIN: "sim.exchange",
DLX: "sim.ex.objenious.dlx",
DEL: "sim.ex.objenious.delayed"
}
const DELAY = 10 * 1000
const BASE_OBENIOUS_KEY = "sim.objenious.#"

View File

@@ -1,10 +1,10 @@
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js";
import { Result } from "sim-shared/domain/Result.js";
import assert from "node:assert";
import { EventBus } from "sim-shared/domain/EventBus.port";
import { SimEvents } from "sim-shared/domain/SimEvents";
import { SimEvents } from "sim-shared/domain/SimEvents.js";
import { uuidv7 } from "uuidv7";
import { CreateOrderDTO, OrderTracking, OrderType, OrderTypeOptions } from "sim-shared/domain/Order.js";
import { EventBus } from "sim-shared/domain/EventBus.port.js";
/**
* Casos de uso de tarjetas sim. Garantiza que todos los metodos usan el mismo bus de mensajes

View File

@@ -18,7 +18,10 @@ export const rmqConnOptions = <RMQConnectionParams>{
}
export const rabbitmqEventBus = new RabbitMQEventBus({
connectionParams: rmqConnOptions
connectionParams: rmqConnOptions,
// La entrada de eventos no tiene que definir exchanges de dlx o delay pero es obligatorio
delayedExchange: "-",
dlxExchange: "-"
})
export async function startRMQClient() {

View File

@@ -21,15 +21,22 @@ export class RabbitMQEventBus implements EventBus {
channel?: ChannelWrapper
connected: Boolean = false
private delayedExchange: string;
private dlxExchange: string;
private connectionOptions: RMQConnectionParams
constructor(args: {
connectionParams: RMQConnectionParams,
buildStructure?: (chan: Channel) => Promise<void>,
maxRetry?: number
maxRetry?: number,
delayedExchange: string,
dlxExchange: string
}) {
this.connectionOptions = args.connectionParams
if (args.buildStructure != undefined) this.buildStructure = args.buildStructure
if (args.maxRetry != undefined) this.maxRetry = args.maxRetry
this.delayedExchange = args.delayedExchange
this.dlxExchange = args.dlxExchange
}
async consume(queue: string, callback: (msg: ConsumeMessage | null) => void) {
@@ -50,23 +57,25 @@ export class RabbitMQEventBus implements EventBus {
async nack(msg: ConsumeMessage, requeue?: boolean) {
if (this.channel == undefined) throw new Error("[RMQ] Canal no iniciallizado");
console.log("NACK: ", msg.properties.headers)
console.log("[i] NACK: ", msg.properties.headers)
const headers = msg.properties.headers || {}
const numberRetry = headers['x-retry-count'] || 0
const routingKey = msg.fields.routingKey
if (numberRetry < this.maxRetry) {
console.log("Delaying")
await this.channel.publish("sim.ex.objenious.delayed", routingKey, msg.content, {
console.log("[i] Delaying ")
// "sim.ex.objenious.delayed"
await this.channel.publish(this.delayedExchange, routingKey, msg.content, {
headers: {
...headers,
'x-retry-count': numberRetry + 1
}
})
} else {
console.log("DeadLetter")
await this.channel.publish("sim.ex.objenious.dlx", routingKey, msg.content, {
console.log("[i] DeadLetter")
//"sim.ex.objenious.dlx"
await this.channel.publish(this.dlxExchange, routingKey, msg.content, {
headers: {
...headers
}

View File

@@ -9,6 +9,6 @@
],
"include": [
"**/*.ts",
"../../packages/sim-shared/**/*.ts",
"**/*.d.ts",
]
}

1633
yarn.lock

File diff suppressed because it is too large Load Diff