diff --git a/deployment/database/migrations/1.1.1_message-id-objenious.sql b/deployment/database/migrations/1.1.1_message-id-objenious.sql new file mode 100644 index 0000000..cb5fc3f --- /dev/null +++ b/deployment/database/migrations/1.1.1_message-id-objenious.sql @@ -0,0 +1,7 @@ +/** +* En la tabla de orders de objenious no hay forma de saber a a que mensaje está Solicitando +* cada operación. +*/ + +ALTER TABLE objenious_operation + ADD COLUMN correlation_id TEXT; diff --git a/packages/sim-consumidor-objenious/aplication/Sim.usecases.ts b/packages/sim-consumidor-objenious/aplication/Sim.usecases.ts index 6d70a06..d0d425a 100644 --- a/packages/sim-consumidor-objenious/aplication/Sim.usecases.ts +++ b/packages/sim-consumidor-objenious/aplication/Sim.usecases.ts @@ -161,6 +161,7 @@ export class SimUseCases { if (resp.status == 200) { console.log("Sim preactivada con exito", resp.data) const operation: ObjeniousOperation = { + correlation_id: preActivateData.correlation_id, operation: "preActivate", iccids: String(preActivateData.identifier.identifiers), status: "noMassID", @@ -220,91 +221,26 @@ export class SimUseCases { } } - // Metodo nuevo public suspend(suspendData: ActionData): () => Promise> { const OPERATION_URL = "/actions/suspendLine" return this.generateUseCase({ correlation_id: suspendData.correlation_id, operationPayload: suspendData, url: OPERATION_URL, - iccid: suspendData.identifier.identifiers, + iccid: suspendData.identifier.identifiers[0], // operation: "suspend" }) - - return async () => { - const req = this.httpClient.client.post(OPERATION_URL, { - ...suspendData - }) - - try { - const response = await req - if (response.status == 200) { - console.log("[o] Sim pausada/suspendida con exito", response.data) - const operation: ObjeniousOperation = { - operation: "susupend", - iccids: String(suspendData.identifier.identifiers), - status: "noMassID", - request_id: response.data.requestId - } - this.logOperation(operation).then().catch(e => console.error(e)) - return >{ - error: undefined, - data: true - } - } else { - // muy mejorable el control de errores - return { - error: String(response.status), - data: undefined - } - } - } catch (error) { - console.error("[Pausa Use case] Error pausa") - return { - error: "Error general pausando/suspendiendo la sim" + suspendData.identifier, - data: undefined - } - } - } } public terminate(terminationData: ActionData): () => Promise> { const OPERATION_URL = "/actions/terminateLine" - return async () => { - const req = this.httpClient.client.post(OPERATION_URL, { - ...terminationData - }) - - try { - const response = await req - - if (response.status == 200) { - console.log("[o] Sim solicitud de cancelacion con exito", response.data) - const operation: ObjeniousOperation = { - operation: "terminate", - iccids: String(terminationData.identifier.identifiers), - status: "noMassID", - request_id: response.data.requestId - } - - return >{ - error: undefined, - data: true - } - } else { - return { - error: String(response.status), - data: undefined - } - } - } catch (error) { - console.error("[x ] Error en la solicitud de terminacion", error) - return >{ - error: "Error cancelando/terminate la sim" + terminationData.identifier, - data: undefined - } - } - } + return this.generateUseCase({ + correlation_id: terminationData.correlation_id, + operationPayload: terminationData, + url: OPERATION_URL, + iccid: terminationData.identifier.identifiers[0], // + operation: "suspend" + }) } diff --git a/packages/sim-consumidor-objenious/domain/DTOs/objeniousapi.ts b/packages/sim-consumidor-objenious/domain/DTOs/objeniousapi.ts index 3f0318e..df5ec36 100644 --- a/packages/sim-consumidor-objenious/domain/DTOs/objeniousapi.ts +++ b/packages/sim-consumidor-objenious/domain/DTOs/objeniousapi.ts @@ -4,7 +4,7 @@ export type ActionData = { dueDate: string, // isodate filter?: {} // no se si hace falta identifier: { - identifiers: string + identifiers: string[] identifierType: "IMSI" | "MSISDN" | "REFERENCE" | "ICCID" | "IMEI" } } diff --git a/packages/sim-consumidor-objenious/index.ts b/packages/sim-consumidor-objenious/index.ts index da34b87..c2d836c 100644 --- a/packages/sim-consumidor-objenious/index.ts +++ b/packages/sim-consumidor-objenious/index.ts @@ -7,6 +7,7 @@ import { PgClient } from "sim-shared/infrastructure/PgClient.js" import { SimUseCases } from "./aplication/Sim.usecases.js" import { SimController } from "./aplication/Sim.controller.js" import { SimRouter } from "./aplication/Sim.router.js" +import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js" async function startWorker() { const rmqClient = await startRMQClient() @@ -18,12 +19,14 @@ async function startWorker() { await pgClient.checkDatabaseConnection() const operationRepository = new ObjeniousOperationsRepository(pgClient) + const orderRepository = new OrderRepository(pgClient) const simActivationController = new SimController( rmqClient, new SimUseCases({ httpClient: httpClient, - operationRepository: operationRepository + operationRepository: operationRepository, + orderRepository: orderRepository }) ) const simRouter = new SimRouter(simActivationController, rmqClient) diff --git a/packages/sim-objenious-cron/.env b/packages/sim-objenious-cron/.env index 06d6f02..4df9ec5 100644 --- a/packages/sim-objenious-cron/.env +++ b/packages/sim-objenious-cron/.env @@ -7,5 +7,6 @@ OBJ_KID=xNfbMiyL1ORXGP8lElhcv8nVaG3EJKye4Lc1YoN3I1E OBJ_BASE_URL=https://api-getway.objenious.com/ws # OBJ_BASE_URL=https://api-getway.objenious.com/ws/test -NOTIFICATION_URL="https://sf-sim-activation.savefamilygps.net/send-activation-mail" +# NOTIFICATION_URL="https://sf-sim-activation.savefamilygps.net/send-activation-mail" +NOTIFICATION_URL="localhost" SIM_ACTIVATION_API_KEY=9e48c4ac-1ab0-4397-b3f3-6c239200dfe6 diff --git a/packages/sim-objenious-cron/index.ts b/packages/sim-objenious-cron/index.ts index 5b44e8f..e9cf2ef 100644 --- a/packages/sim-objenious-cron/index.ts +++ b/packages/sim-objenious-cron/index.ts @@ -4,6 +4,7 @@ import { PgClient } from "sim-shared/infrastructure/PgClient.js" import { httpInstance } from "./config/httpClient.config.js" import { CheckObjeniousRequests } from "./tasks/check_objenious_request.js" import { ObjeniousOperationsRepository } from "sim-shared/infrastructure/ObjeniousOperationRepository.js" +import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js" async function startCron() { const commonSettings = { @@ -16,13 +17,16 @@ async function startCron() { await pgClient.checkDatabaseConnection() await pgClient.checkDatabaseConnection() const operationRepository = new ObjeniousOperationsRepository(pgClient) + const orderRepository = new OrderRepository(pgClient) const objTask = new CheckObjeniousRequests( operationRepository, - httpClient + orderRepository, + httpClient, ) await objTask.getPendingOperations() + const interval = setInterval(async () => { console.log("Updating...") await objTask.getPendingOperations() diff --git a/packages/sim-objenious-cron/tasks/check_objenious_request.ts b/packages/sim-objenious-cron/tasks/check_objenious_request.ts index b38fa7a..a60fe7a 100644 --- a/packages/sim-objenious-cron/tasks/check_objenious_request.ts +++ b/packages/sim-objenious-cron/tasks/check_objenious_request.ts @@ -16,43 +16,47 @@ export class CheckObjeniousRequests { * TODO: meter a una funcion a parte task con los 3 pasos */ public async getPendingOperations() { + // 1. Se obtienen todas las operaciones pendientes de la BDD const pendingOperations = await this.operationsRepository.getPendingOperations() - if (pendingOperations.error != undefined) { throw new Error("Error obteniendo las tareas pendientes " + pendingOperations.error) } if (pendingOperations.data == undefined || pendingOperations.data.length == 0) { - //Nada pendiente + console.log("[cron] No hay operaciones pendientes de Objenious") return; } + // 2. Clasificación de las tareas pendientes + // Erroneas => no se les ha dado un request_id, no se pueden comprobar const erroneas = pendingOperations.data .filter((e) => e.request_id == undefined) - + // Todas las validas const operacionesValidas = pendingOperations.data .filter((e) => e.request_id != undefined) - + // Validas sin MassId const solicitarMassId = operacionesValidas .filter((e) => e.mass_action_id == undefined) - + // Validas con MassId const consultarEstado = pendingOperations.data .filter(e => e.mass_action_id != undefined) + // TODO: Validas sin/con massID que lleven mucho tiempo sin actualizarse console.log("[cron] Solicitando mass id para", solicitarMassId.map(e => e.id)) - const newMassActions = await this.getMassIdFromRequest(solicitarMassId) - const merged = [...newMassActions || [], ...consultarEstado] console.log("[cron] Solicitando status para", merged.map(e => e.id)) - const result = await this.getMassActionsStatus(merged) } + /** + * Para una lista de operaciones **con mass_action_id** se comprueba si han tenido alguna actualizacion + * Devuelve el numero de operaciones comprobadas. + */ private async getMassActionsStatus(requestList: ObjeniousOperation[]) { - if (requestList.length == 0) return; + if (requestList.length == 0) return 0; const operationsList = structuredClone(requestList) const PATH = "/actions/massActions/" @@ -123,6 +127,14 @@ export class CheckObjeniousRequests { console.log("[i] lineData", lineData.content[0]) const msisdn = lineData.content[0].identifier.msisdn + if (originalAction.correlation_id != undefined) { + this.orderRepository.finishOrder({ correlation_id: originalAction.correlation_id }) + .then(e => console.log("[o] Finalizada order", e)) + .catch(e => { + console.error("[x] Error finalizando la order ", e) + console.error(e) + }) + } this.notifyFinalization({ ...originalAction, msisdn diff --git a/packages/sim-shared/domain/Order.ts b/packages/sim-shared/domain/Order.ts index 2ff6e73..30ec573 100644 --- a/packages/sim-shared/domain/Order.ts +++ b/packages/sim-shared/domain/Order.ts @@ -72,3 +72,14 @@ export type UpdateOrderDTO = new_status: OrderStatus, reason?: string } + +export type FinishOrderDTO = + ( + { id: number, correlation_id?: never } | + { id?: never, correlation_id: string } + ) + & + { + reason?: string + } + diff --git a/packages/sim-shared/domain/operationsRepository.port.ts b/packages/sim-shared/domain/operationsRepository.port.ts index 1892b86..7af02c2 100644 --- a/packages/sim-shared/domain/operationsRepository.port.ts +++ b/packages/sim-shared/domain/operationsRepository.port.ts @@ -10,6 +10,8 @@ export interface IOperationsRepository { export type ObjeniousOperation = { id?: number; + /** Uuid del mensaje asociado a la operacion */ + correlation_id?: string; operation: string; retry_count?: number; max_retry?: number; diff --git a/packages/sim-shared/infrastructure/OrderRepository.ts b/packages/sim-shared/infrastructure/OrderRepository.ts index e0f9a6a..e80214e 100644 --- a/packages/sim-shared/infrastructure/OrderRepository.ts +++ b/packages/sim-shared/infrastructure/OrderRepository.ts @@ -2,7 +2,7 @@ * TODO: Usar */ import { PoolClient, QueryResult, QueryResultRow } from "pg"; -import { CreateOrderDTO, OrderTracking, UpdateOrderDTO } from "../domain/Order.js"; +import { CreateOrderDTO, FinishOrderDTO, OrderTracking, UpdateOrderDTO } from "../domain/Order.js"; import { Result } from "../domain/Result.js"; import { PgClient } from "./PgClient.js"; import assert from "node:assert"; @@ -177,7 +177,7 @@ export class OrderRepository { const client = await this.pgClient.connect(); await client.query('BEGIN'); - const idType = ('id' in args) ? "correlation_id" : "id" + const idType = ('id' in args) ? "id" : "correlation_id" const idValue = (args.id != undefined) ? args.id : args.correlation_id // 1. Se consulta la order de base @@ -262,18 +262,29 @@ export class OrderRepository { } - public async finishOrder(args: { id: number, reason?: string }) { + public async finishOrder(args: FinishOrderDTO) { const client = await this.pgClient.connect(); + assert((args.id != undefined) != (args.correlation_id != undefined)) await client.query('BEGIN'); + const idType = ('id' in args) ? "id" : "correlation_id" + const idValue = (args.id != undefined) ? args.id : args.correlation_id + // 1. Se consulta la order de base const qCurrentOrder = ` SELECT * FROM order_tracking - WHERE id = $1 + WHERE ${idType} = $1 ` - const vCurrentOrder = [args.id] + const vCurrentOrder = [idValue] const currentOrderResult = await this.getFirst(client.query>(qCurrentOrder, vCurrentOrder)) + const orderId = currentOrderResult.data?.id + + if (orderId == undefined) { + return { + error: "El order a actualizar no existe " + idType + ": " + idValue + } + } if (currentOrderResult.error != undefined) { await client.query("ROLLBACK") @@ -293,7 +304,7 @@ export class OrderRepository { WHERE id = $1 RETURNING id, status, update_date; ` - const vOrderTracking = [args.id] + const vOrderTracking = [orderId] const updatedOrderResult = await this.getFirst( client.query<{ id: number, status: string, update_date: string }>(uOrderTracking, vOrderTracking) )