Router intermedio para las ops de objenious
This commit is contained in:
@@ -27,10 +27,6 @@ export class RabbitMQEventBus implements EventBus {
|
||||
async consume(queue: string, callback: (msg: ConsumeMessage | null) => void) {
|
||||
// Comproaciones antes de escuchar
|
||||
if (this.channel == undefined) throw new Error("[RMQ] Canal no iniciallizado");
|
||||
|
||||
// El binding (cola -> [routingkey] -> exchange) lo hago por configuracion. Meter colas a demanda?
|
||||
//await this.channel.prefetch(1)
|
||||
|
||||
await this.channel.consume(queue, callback)
|
||||
}
|
||||
|
||||
@@ -55,7 +51,7 @@ export class RabbitMQEventBus implements EventBus {
|
||||
try {
|
||||
this.connection = await this.createConnection();
|
||||
if (this.connection == undefined) throw new Error("[RMQ] Error crecreando la conexion")
|
||||
this.channel = await this.createConfirmChannel()
|
||||
this.channel = await this.createChannel()
|
||||
this.channel.on("close", () => {
|
||||
console.log("[RMQ] Canal desconectado")
|
||||
setTimeout(async () => {
|
||||
@@ -116,14 +112,14 @@ export class RabbitMQEventBus implements EventBus {
|
||||
console.log(`[RMQ] Reintentando conexion`)
|
||||
});
|
||||
|
||||
connection.on("disconnect", (err) => {
|
||||
console.error(`[RMQ] Servidor Rabbitmq desconectado, reintentando ...`)
|
||||
connection.on("disconnect", (err: unknown) => {
|
||||
console.error(`[RMQ] Servidor Rabbitmq desconectado, reintentando ... :: ${err}`)
|
||||
})
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
protected async createConfirmChannel() {
|
||||
protected async createChannel() {
|
||||
if (this.connection == undefined) throw new Error("[RMQ] Intentando crear un canal sin una conexion")
|
||||
const channel = this.connection.createChannel({
|
||||
json: true,
|
||||
|
||||
@@ -38,7 +38,7 @@ type AuthHeaders = {
|
||||
exp: number,
|
||||
}
|
||||
|
||||
const PRIVATE_KEY_PATH = __dirname + "/../obj.pem"
|
||||
const PRIVATE_KEY_PATH = env.OBJ_PEM_PATH
|
||||
|
||||
const GET_TOKEN_URL = "https://idp.docapost.io/auth/realms/GETWAY/protocol/openid-connect/token"
|
||||
const REFRESH_TOKEN_URL = GET_TOKEN_URL
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { EventBus } from "#shared/domain/EventBus.port";
|
||||
import { ConsumeMessage } from "amqplib";
|
||||
import { SimUseCases } from "./Sim.usecases";
|
||||
|
||||
export class SimController {
|
||||
private eventBus: EventBus;
|
||||
private useCases: SimUseCases
|
||||
|
||||
constructor(
|
||||
eventBus: EventBus,
|
||||
useCases: SimUseCases
|
||||
) {
|
||||
this.eventBus = eventBus
|
||||
this.useCases = useCases
|
||||
|
||||
}
|
||||
|
||||
public async activateSim(msg: ConsumeMessage | null) {
|
||||
return async () => {
|
||||
if (!this.validateActivationMsg(msg)) {
|
||||
throw new Error("Error consumiendo el mensaje no es valido")
|
||||
}
|
||||
const msgData = Buffer.from(JSON.parse(msg?.content.toString("utf-8") || "{}").data)
|
||||
console.log("Mensaje procesado", String(msgData))
|
||||
|
||||
// Caso de uso de activaciones
|
||||
await this.useCases.activate({
|
||||
dueDate: new Date().toString(),
|
||||
identifier: {
|
||||
identifierType: "ICCID",
|
||||
identifiers: ["1234"]
|
||||
}
|
||||
})()
|
||||
// TODO: comprobar el resultado de la opreacion
|
||||
this.eventBus.ack(msg!)
|
||||
}
|
||||
}
|
||||
|
||||
public async pauseSim(msg: ConsumeMessage | null) {
|
||||
return async () => {
|
||||
if (!this.validateActivationMsg(msg)) {
|
||||
throw new Error("Error consumiendo el mensaje no es valido")
|
||||
}
|
||||
const msgData = Buffer.from(JSON.parse(msg?.content.toString("utf-8") || "{}").data)
|
||||
console.log("Mensaje procesado", String(msgData))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* - Loguear motivos de la no validacion
|
||||
*/
|
||||
private validateActivationMsg(msg: ConsumeMessage | null) {
|
||||
if (msg == undefined) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
48
packages/sim-consumidor-objenious/aplication/Sim.router.ts
Normal file
48
packages/sim-consumidor-objenious/aplication/Sim.router.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Dirige cada mensaje dependiendo de el tipo de accion que contenga
|
||||
*/
|
||||
|
||||
import { ConsumeMessage } from "amqplib";
|
||||
import { SimController } from "./Sim.controller";
|
||||
|
||||
export class SimRouter {
|
||||
private simController: SimController
|
||||
|
||||
private routeMap: Map<string, (m: ConsumeMessage | null) => void> = new Map()
|
||||
|
||||
constructor(simController: SimController) {
|
||||
this.simController = simController
|
||||
|
||||
// No me gusta que se defina en el constructor
|
||||
this.routeMap = new Map([
|
||||
["activate", this.simController.activateSim],
|
||||
["pause", this.simController.pauseSim],
|
||||
])
|
||||
this.route = this.route.bind(this)
|
||||
}
|
||||
|
||||
public route(msg: ConsumeMessage | null) {
|
||||
if (msg == undefined) {
|
||||
console.error("Mensaje vacio")
|
||||
return;
|
||||
}
|
||||
|
||||
const routingKey = msg.fields.routingKey
|
||||
const action = routingKey.split(".")[2]
|
||||
|
||||
if (action == undefined) {
|
||||
console.error("La routing key no tiene una accion definida")
|
||||
console.error(msg.fields)
|
||||
}
|
||||
|
||||
const accionEjecutable = this.routeMap.get(action)
|
||||
|
||||
if (accionEjecutable == undefined) {
|
||||
console.error("La accion del mensaje no tiene un controlador asociado")
|
||||
} else {
|
||||
console.log("Ejecutado operacion", action)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
48
packages/sim-consumidor-objenious/aplication/Sim.usecases.ts
Normal file
48
packages/sim-consumidor-objenious/aplication/Sim.usecases.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { ActivationData } from "#domain/DTOs/objeniousapi"
|
||||
import { HttpClient } from "#shared/infrastructure/HTTPClient"
|
||||
|
||||
// TODO: Pasar a un archivo de DTOs
|
||||
|
||||
|
||||
export class SimUseCases {
|
||||
private httpClient: HttpClient
|
||||
|
||||
constructor(args: {
|
||||
|
||||
httpClient: HttpClient
|
||||
}) {
|
||||
this.httpClient = args.httpClient
|
||||
}
|
||||
|
||||
public activate(activationData: ActivationData) {
|
||||
const OPERATION_URL = "/actions/preactivate"
|
||||
return async () => {
|
||||
const req = this.httpClient.client.post(OPERATION_URL, {
|
||||
...activationData
|
||||
})
|
||||
|
||||
try {
|
||||
const e = await req
|
||||
console.log("Activacion con exito", e.data)
|
||||
} catch (error) {
|
||||
console.error("Error activando ", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public pause(activationData: ActivationData) {
|
||||
const OPERATION_URL = "/actions/pause"
|
||||
return async () => {
|
||||
const req = this.httpClient.client.post("/actions/pause", {
|
||||
...activationData
|
||||
})
|
||||
|
||||
try {
|
||||
const e = await req
|
||||
console.log("Sim pausada con exito", e.data)
|
||||
} catch (error) {
|
||||
console.error("Error pausa", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import { EventBus } from "#shared/domain/EventBus.port";
|
||||
import { ConsumeMessage } from "amqplib";
|
||||
import { SimActivationUseCase } from "./SimActivation.usecase";
|
||||
|
||||
export class SimActivationController {
|
||||
private eventBus: EventBus;
|
||||
private useCases: {
|
||||
activation: SimActivationUseCase
|
||||
}
|
||||
|
||||
constructor(
|
||||
eventBus: EventBus,
|
||||
useCases: {
|
||||
activation: SimActivationUseCase
|
||||
}
|
||||
) {
|
||||
this.eventBus = eventBus
|
||||
this.useCases = useCases
|
||||
// No se si hay un sistema mejor
|
||||
// convertor en const () => {} para conservar el contexto??
|
||||
this.activateSim = this.activateSim.bind(this)
|
||||
}
|
||||
|
||||
public async activateSim(msg: ConsumeMessage | null) {
|
||||
if (!this.validateActivationMsg(msg)) {
|
||||
throw new Error("Error consumiendo el mensaje no es valido")
|
||||
}
|
||||
const msgData = Buffer.from(JSON.parse(msg?.content.toString("utf-8") || "{}").data)
|
||||
console.log("Mensaje procesado", String(msgData))
|
||||
|
||||
// Caso de uso de activaciones
|
||||
await this.useCases.activation.run({
|
||||
dueDate: new Date().toString(),
|
||||
identifier: {
|
||||
identifierType: "ICCID",
|
||||
identifiers: ["1234"]
|
||||
}
|
||||
})
|
||||
// TODO: comprobar el resultado de la opreacion
|
||||
this.eventBus.ack(msg!)
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* - Loguear motivos de la no validacion
|
||||
*/
|
||||
private validateActivationMsg(msg: ConsumeMessage | null) {
|
||||
if (msg == undefined) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,6 @@
|
||||
import { ActivationData } from "#domain/DTOs/objeniousapi"
|
||||
import { HttpClient } from "#shared/infrastructure/HTTPClient"
|
||||
|
||||
// TODO: Pasar a un archivo de DTOs
|
||||
|
||||
export type ActivationData = {
|
||||
dueDate: string, // isodate
|
||||
filter?: {} // no se si hace falta
|
||||
identifier: {
|
||||
identifiers: string[]
|
||||
identifierType: "IMSI" | "MSISDN" | "REFERENCE" | "ICCID" | "IMEI"
|
||||
}
|
||||
}
|
||||
|
||||
export type ResponseError = {
|
||||
error: string,
|
||||
detail: Object[]
|
||||
}
|
||||
|
||||
export class SimActivationUseCase {
|
||||
private httpClient: HttpClient
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
export type ActivationData = {
|
||||
dueDate: string, // isodate
|
||||
filter?: {} // no se si hace falta
|
||||
identifier: {
|
||||
identifiers: string[]
|
||||
identifierType: "IMSI" | "MSISDN" | "REFERENCE" | "ICCID" | "IMEI"
|
||||
}
|
||||
}
|
||||
|
||||
export type ResponseError = {
|
||||
error: string,
|
||||
detail: Object[]
|
||||
}
|
||||
@@ -1,22 +1,23 @@
|
||||
|
||||
import { startRMQClient } from "#config/eventBus.config"
|
||||
import { httpInstance } from "#config/httpClient.config"
|
||||
import { SimActivationController } from "aplication/SimActivation.controller"
|
||||
import { SimActivationUseCase } from "aplication/SimActivation.usecase"
|
||||
import { SimController } from "aplication/Sim.controller"
|
||||
import { SimRouter } from "aplication/Sim.router"
|
||||
import { SimUseCases } from "aplication/Sim.usecases"
|
||||
|
||||
async function startWorker() {
|
||||
const rmqClient = await startRMQClient()
|
||||
const httpClient = httpInstance
|
||||
const simActivationController = new SimActivationController(
|
||||
const simActivationController = new SimController(
|
||||
rmqClient,
|
||||
{
|
||||
activation: new SimActivationUseCase({
|
||||
httpClient: httpClient
|
||||
})
|
||||
}
|
||||
new SimUseCases({
|
||||
httpClient: httpClient
|
||||
})
|
||||
)
|
||||
const simRouter = new SimRouter(simActivationController)
|
||||
|
||||
rmqClient.consume("sim.objenious", simActivationController.activateSim)
|
||||
// de momento solo una cola por simplificar
|
||||
rmqClient.consume("sim.objenious", simRouter.route)
|
||||
}
|
||||
|
||||
startWorker()
|
||||
|
||||
Reference in New Issue
Block a user