From 8a28c54c5d310fec99cb43b66ac79ca40cd5a2a4 Mon Sep 17 00:00:00 2001 From: Alvar San Martin Date: Fri, 6 Feb 2026 12:14:46 +0100 Subject: [PATCH] Problema de actuallizacion de operation resuelto --- deployment/database/01-objenious.sql | 45 ++++--- deployment/database/init.sql | 45 ++++--- docs/sim-objenious/Get all requests.bru | 6 +- ... action copy.bru => Mass action by id.bru} | 4 +- docs/sim-objenious/Mass action list.bru | 15 ++- packages/shared/infrastructure/HTTPClient.ts | 4 +- .../domain/operationsRepository.port.ts | 6 +- .../infrastructure/OperationRepository.ts | 50 +++++--- .../tasks/check_objenious_request.ts | 117 +++++++++++------- 9 files changed, 177 insertions(+), 115 deletions(-) rename docs/sim-objenious/{Mass action copy.bru => Mass action by id.bru} (91%) diff --git a/deployment/database/01-objenious.sql b/deployment/database/01-objenious.sql index 06fc472..fde74f0 100644 --- a/deployment/database/01-objenious.sql +++ b/deployment/database/01-objenious.sql @@ -5,19 +5,20 @@ CREATE TYPE status_enum AS ENUM ('noRequestID','noMassID','running','finished',' -- Para una o mas lineas se pueden lanzar operacione que no sabemos -- con certeza cuando van a terminar. CREATE TABLE if not exists objenious_operation ( - id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, - retry_count INT DEFAULT 0, - max_retry INT DEFAULT 5, - max_date_retry TIMESTAMP DEFAULT NULL, - iccids TEXT, - request_id TEXT, - mass_action_id TEXT, - operation TEXT NOT NULL, - start_date TIMESTAMP NOT NULL DEFAULT now(), - last_change_date TIMESTAMP NOT NULL DEFAULT now(), - end_date TIMESTAMP, - error TEXT, - status status_enum + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + retry_count INT DEFAULT 0, + max_retry INT DEFAULT 5, + max_date_retry TIMESTAMP DEFAULT NULL, + iccids TEXT, + request_id TEXT, + mass_action_id TEXT, + operation TEXT NOT NULL, + start_date TIMESTAMP NOT NULL DEFAULT now(), + last_change_date TIMESTAMP NOT NULL DEFAULT now(), + end_date TIMESTAMP, + error TEXT, + status status_enum, + objenious_status TEXT ); -- operaciones pendientes para revisar @@ -26,13 +27,17 @@ CREATE INDEX IF NOT EXISTS pending_operations WHERE end_date IS NULL; CREATE TABLE if not exists objenious_operation_change ( - id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, - operation_id BIGINT, - creation_date TIMESTAMP NOT NULL DEFAULT now(), - error TEXT, - new_status status_enum, - new_request_id TEXT, - new_mass_action_id TEXT, + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + operation_id BIGINT, + creation_date TIMESTAMP NOT NULL DEFAULT now(), + error TEXT, + new_status status_enum, + previous_status status_enum, + new_objenious_status TEXT, + previous_objenious_status TEXT, + new_request_id TEXT, + new_mass_action_id TEXT, + CONSTRAINT fk_operation_id FOREIGN KEY(operation_id) REFERENCES objenious_operation(id) ); diff --git a/deployment/database/init.sql b/deployment/database/init.sql index d8ce9df..db8e518 100644 --- a/deployment/database/init.sql +++ b/deployment/database/init.sql @@ -109,19 +109,20 @@ CREATE TYPE status_enum AS ENUM ('noRequestID','noMassID','running','finished',' -- Para una o mas lineas se pueden lanzar operacione que no sabemos -- con certeza cuando van a terminar. CREATE TABLE if not exists objenious_operation ( - id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, - retry_count INT DEFAULT 0, - max_retry INT DEFAULT 5, - max_date_retry TIMESTAMP DEFAULT NULL, - iccids TEXT, - request_id TEXT, - mass_action_id TEXT, - operation TEXT NOT NULL, - start_date TIMESTAMP NOT NULL DEFAULT now(), - last_change_date TIMESTAMP NOT NULL DEFAULT now(), - end_date TIMESTAMP, - error TEXT, - status status_enum + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + retry_count INT DEFAULT 0, + max_retry INT DEFAULT 5, + max_date_retry TIMESTAMP DEFAULT NULL, + iccids TEXT, + request_id TEXT, + mass_action_id TEXT, + operation TEXT NOT NULL, + start_date TIMESTAMP NOT NULL DEFAULT now(), + last_change_date TIMESTAMP NOT NULL DEFAULT now(), + end_date TIMESTAMP, + error TEXT, + status status_enum, + objenious_status TEXT ); -- operaciones pendientes para revisar @@ -130,13 +131,17 @@ CREATE INDEX IF NOT EXISTS pending_operations WHERE end_date IS NULL; CREATE TABLE if not exists objenious_operation_change ( - id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, - operation_id BIGINT, - creation_date TIMESTAMP NOT NULL DEFAULT now(), - error TEXT, - new_status status_enum, - new_request_id TEXT, - new_mass_action_id TEXT, + id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, + operation_id BIGINT, + creation_date TIMESTAMP NOT NULL DEFAULT now(), + error TEXT, + new_status status_enum, + previous_status status_enum, + new_objenious_status TEXT, + previous_objenious_status TEXT, + new_request_id TEXT, + new_mass_action_id TEXT, + CONSTRAINT fk_operation_id FOREIGN KEY(operation_id) REFERENCES objenious_operation(id) ); diff --git a/docs/sim-objenious/Get all requests.bru b/docs/sim-objenious/Get all requests.bru index 59f8b84..aaaa235 100644 --- a/docs/sim-objenious/Get all requests.bru +++ b/docs/sim-objenious/Get all requests.bru @@ -5,14 +5,14 @@ meta { } get { - url: {{actionsUrl}}/requests/?pageSize=100&request.actionType=PREACTIVAION + url: {{actionsUrl}}/requests/?pageSize=10 body: formUrlEncoded auth: bearer } params:query { - pageSize: 100 - request.actionType: PREACTIVAION + pageSize: 10 + ~request.actionType: PREACTIVAION } auth:bearer { diff --git a/docs/sim-objenious/Mass action copy.bru b/docs/sim-objenious/Mass action by id.bru similarity index 91% rename from docs/sim-objenious/Mass action copy.bru rename to docs/sim-objenious/Mass action by id.bru index 5a7f36f..f5e1853 100644 --- a/docs/sim-objenious/Mass action copy.bru +++ b/docs/sim-objenious/Mass action by id.bru @@ -1,5 +1,5 @@ meta { - name: Mass action copy + name: Mass action by id type: http seq: 15 } @@ -24,7 +24,7 @@ body:json { } vars:pre-request { - id: 5189837 + id: 5192767 } settings { diff --git a/docs/sim-objenious/Mass action list.bru b/docs/sim-objenious/Mass action list.bru index f72e52a..b83a34a 100644 --- a/docs/sim-objenious/Mass action list.bru +++ b/docs/sim-objenious/Mass action list.bru @@ -5,27 +5,34 @@ meta { } get { - url: {{actionsUrl}}/massActions/ + url: {{actionsUrl}}/massActions?massActionId=5192767 body: formUrlEncoded auth: bearer } +params:query { + massActionId: 5192767 + ~identifier.identifierType: ICCID + ~identifier.identifiers: 8933201125065160463,8933201125065160422 +} + auth:bearer { token: {{ws-access-token-partenaire}} } body:json { - { + "identifier": { "identifiers": ["8933201124059175967"], "identifierType": "ICCID" } - } + } body:form-urlencoded { identifier.identifierType: ICCID - identifier.identifiers: 8933201124059176320 + identifier.identifiers: 8933201125065160463 + ~massActionId: 5192767 } vars:pre-request { diff --git a/packages/shared/infrastructure/HTTPClient.ts b/packages/shared/infrastructure/HTTPClient.ts index 8c5a50e..b638902 100644 --- a/packages/shared/infrastructure/HTTPClient.ts +++ b/packages/shared/infrastructure/HTTPClient.ts @@ -1,5 +1,5 @@ import axios, { AxiosInstance } from "axios" -import { JWTToken } from "../domain/JWT" +import { JWTToken } from "../domain/JWT.js" export type JWTProvider = { /** El servidor está solicitando un token nuevo o refrescando el actual*/ @@ -49,7 +49,7 @@ export class HttpClient { async (error) => { // TODO: Esta parte no tiene tipos, hay que asegurar el error const req = error.config - console.error("[http] Error en la respuesta ", error.response.data) + console.error("[http] Error en la respuesta ", error, error.response) if (error.response?.status == 401) { this.jwtManager.getAccessToken() } diff --git a/packages/sim-consumidor-objenious/domain/operationsRepository.port.ts b/packages/sim-consumidor-objenious/domain/operationsRepository.port.ts index 50c0b03..9370e9f 100644 --- a/packages/sim-consumidor-objenious/domain/operationsRepository.port.ts +++ b/packages/sim-consumidor-objenious/domain/operationsRepository.port.ts @@ -1,6 +1,6 @@ import { Result } from "#shared/domain/Result.js"; -export type StatusEnum = Objenious.Status | 'noMassID'; +export type StatusEnum = 'error' | 'finished' | 'noRequestId' | 'running' | 'noMassID'; export interface IOperationsRepository { createOperation(data: ObjeniousOperation): Promise> @@ -20,6 +20,7 @@ export type ObjeniousOperation = { end_date?: Date | null; error?: string | null; status: StatusEnum; + objenioius_status: string; last_change_date?: string; } @@ -29,6 +30,9 @@ export type ObjeniousOperationChange = { info?: string | null; error?: string | null; new_status: StatusEnum; + previous_status?: StatusEnum; + new_objenious_status?: string; + previous_objenious_status?: string; new_request_id?: string; new_mass_action_id?: string; } diff --git a/packages/sim-consumidor-objenious/infrastructure/OperationRepository.ts b/packages/sim-consumidor-objenious/infrastructure/OperationRepository.ts index 9838004..0d0eaea 100644 --- a/packages/sim-consumidor-objenious/infrastructure/OperationRepository.ts +++ b/packages/sim-consumidor-objenious/infrastructure/OperationRepository.ts @@ -16,8 +16,8 @@ export class OperationsRepository implements IOperationsRepository { INSERT INTO objenious_operation (operation, iccids, status, max_retry, request_id) VALUES ($1, $2, $3, $4, $5) RETURNING *`; - const iccids = data.iccids.join(",") - const values = [data.operation, data.iccids, data.status, data.max_retry, data.request_id]; + const iccids = JSON.stringify(data.iccids) + const values = [data.operation, iccids, data.status, data.max_retry, data.request_id]; const { rows } = await this.pgClient.query(query, values); return >{ data: rows[0] @@ -26,34 +26,52 @@ export class OperationsRepository implements IOperationsRepository { async updateOperation(data: ObjeniousOperationChange): Promise> { const client = await this.pgClient.connect(); - const { new_status, error, new_request_id, new_mass_action_id, id } = data + const { + new_status, + previous_status, + error, + new_request_id, + new_mass_action_id, + operation_id, + new_objenious_status, + previous_objenious_status + } = data + try { await client.query('BEGIN'); - - // 1. Actualizar objenious_operation + // 1. Actualizar objenious_operation (la operacion base) + const updateParams = [operation_id, new_status, error, new_request_id, new_mass_action_id, new_objenious_status] + console.log("updateParams", updateParams) const updateOpQuery = ` UPDATE objenious_operation SET - status = $1, - error = COALESCE($2,error), - request_id = COALESCE($3, request_id), - mass_action_id = COALESCE($4, mass_action_id), + status = $2::status_enum, + error = COALESCE($3,error), + request_id = COALESCE($4, request_id), + mass_action_id = COALESCE($5, mass_action_id), last_change_date = now(), - end_date = CASE WHEN $1 IN ('finished', 'error') THEN now() ELSE end_date END - WHERE id = $5`; - const operation = await client.query(updateOpQuery, [new_status, error, new_request_id, new_mass_action_id, id]); + end_date = CASE WHEN $2::status_enum IN ('finished', 'error') THEN now() ELSE end_date END, + objenious_status = $6 + WHERE id = $1`; - // 2. Nuevo registro en objenious_operation_change + const operation = await client.query( + updateOpQuery, updateParams) + + console.log("Operacion base acualizada") + // 2. Nuevo registro en objenious_operation_change (indica un cambio de estado) const insertChangeQuery = ` - INSERT INTO objenious_operation_change (operation_id, new_status, error, new_request_id, new_mass_action_id) - VALUES ($1, $2, $3, $4, $5)`; - await client.query(insertChangeQuery, [id, new_status, error, new_request_id, new_mass_action_id]); + INSERT INTO objenious_operation_change (operation_id, new_status, previous_status, error, new_request_id, new_mass_action_id, new_objenious_status, previous_objenious_status) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`; + await client.query(insertChangeQuery, [operation_id, new_status, previous_status, error, new_request_id, new_mass_action_id, new_objenious_status, previous_objenious_status]); + console.log("Nuevo registro de actualizacion") await client.query('COMMIT'); return >{ data: operation.rows[0] } } catch (e) { + console.error("Error añadiendo actualizacion de la operation", e) + console.error("datos errorneos", data) await client.query('ROLLBACK'); return >{ data: undefined, diff --git a/packages/sim-objenious-cron/tasks/check_objenious_request.ts b/packages/sim-objenious-cron/tasks/check_objenious_request.ts index 8de5566..ed66845 100644 --- a/packages/sim-objenious-cron/tasks/check_objenious_request.ts +++ b/packages/sim-objenious-cron/tasks/check_objenious_request.ts @@ -1,5 +1,6 @@ -import { IOperationsRepository, Objenious, ObjeniousOperation, ObjeniousOperationChange } from "#objenious-shared/domain/operationsRepository.port.js" +import { IOperationsRepository, Objenious, ObjeniousOperation, ObjeniousOperationChange, StatusEnum } from "#objenious-shared/domain/operationsRepository.port.js" import { HttpClient } from "#shared/infrastructure/HTTPClient.js"; +import { constants } from "node:buffer"; export class CheckObjeniousRequests { constructor( @@ -52,71 +53,93 @@ export class CheckObjeniousRequests { if (requestList.length == 0) return; const operationsList = structuredClone(requestList) - const PATH = "/actions/massActions" + const PATH = "/actions/massActions/" const updated = [] const iccids = operationsList .map(e => e.iccids) .flat() + const mass_actions = operationsList + .filter(e => e.mass_action_id != undefined) + const iccidSet = new Set(iccids) + console.log("iccidSet", iccidSet) - const req = this.httpClient.client.get(PATH, { - params: { - "identifier.identifierType": "ICCID", - "identifier.identifiers": Array.from(iccidSet) - } - }) - let res; - // 1. Comprobacion de la request. - try { - res = await req - } catch (e) { - console.error("Error comprobando el estado de ", iccidSet, e) - return; - } + // 1. Una peticion por cada accion a comprobar + // Las peticiones por iccid u otro filtro tardan ~50s + for (const originalAction of mass_actions) { - const { data, status } = res - - if (status != 200 || data == undefined) { - console.error("Error buscando los massActions") - return - } - - if (data.length == 0) return; - - // 2. Por cada elemento de la respuesta se comprueba si ha habido un cambio de estado - for (const action of data) { - const { id, status } = action - const original = operationsList.find(e => e.id == id) - - console.log("Comprobando", action, original) - - if (original == undefined) continue; - - if (status != original?.status) { - console.log("Actualizando", action, original) - const updateData: ObjeniousOperationChange = { - operation_id: original.id!, - new_status: status, + const req = this.httpClient.client.get(PATH + originalAction.mass_action_id, { + params: { } - original.status = status; - original.last_change_date = new Date().toISOString() + }) - if (action.info != undefined) { - updateData.info = action.info + let res; + // 1. Comprobacion de la request. + try { + res = await req + } catch (e) { + console.error("Error comprobando el estado de ", originalAction) + console.error("Error: ", e) + return; + } + + const { data } = res + + console.log("Estado de : ", originalAction.mass_action_id, originalAction.iccids) + console.log(res.status, data) + + if (res.status != 200 || data == undefined) { + console.error("Error buscando los massActions") + continue; + } + + // 2. Se comprueba si ha habido un cambio de estado + const { id, status, info } = data + + if (status != originalAction.objenioius_status) { + console.log("Actualizando", originalAction, status) + const uorStatus = this.mapStatus(status) + const updateData: ObjeniousOperationChange = { + operation_id: originalAction.id!, + new_objenious_status: status, + previous_objenious_status: originalAction.objenioius_status, + new_status: uorStatus, + previous_status: originalAction.status + } + + originalAction.status = uorStatus; + originalAction.objenioius_status = status; + originalAction.last_change_date = new Date().toISOString() + + if (info != undefined) { + updateData.info = info } try { + console.log("Subiendo un update") + console.log(updateData) await this.operationsRepository.updateOperation(updateData) - updated.push(action) + updated.push(originalAction) } catch (e) { - console.error("Error actualizando el estado de ", action, e) + console.error("Error actualizando el estado de ", originalAction, e) return; } } } + } + private mapStatus(objStatus: string) { + const sanitizedStatus = objStatus.trim().toLowerCase() + // No tengo el resto porque no aparecen en la documentación + // asumo que todos los demas sn running y se deben volver a comrobar + const equivalentMap = new Map([ + ["terminé", "finished"] + ]) + const res = equivalentMap.get(objStatus) + if (res == undefined) return "running" + return res } /** @@ -154,7 +177,7 @@ export class CheckObjeniousRequests { if (res.status == 200 && res.data != undefined && massActionId != undefined) { const updateData: ObjeniousOperationChange = { operation_id: request.id, - new_status: "IN_PROGRESS", + new_status: "running", new_mass_action_id: String(massActionId) } @@ -163,7 +186,7 @@ export class CheckObjeniousRequests { request.mass_action_id = String(massActionId) } } catch (e) { - console.log("Error actualizando ell estado de ", request) + console.log("Error actualizando el estado de ", request) continue; }