Problema de actuallizacion de operation resuelto

This commit is contained in:
2026-02-06 12:14:46 +01:00
parent 05138a44c9
commit 8a28c54c5d
9 changed files with 177 additions and 115 deletions

View File

@@ -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)
);

View File

@@ -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)
);

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -1,5 +1,5 @@
import axios, { AxiosInstance } from "axios"
import { JWTToken } from "../domain/JWT"
import { JWTToken } from "../domain/JWT.js"
export type JWTProvider<T> = {
/** 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()
}

View File

@@ -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<Result<string, ObjeniousOperation>>
@@ -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;
}

View File

@@ -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 <Result<string, ObjeniousOperation>>{
data: rows[0]
@@ -26,34 +26,52 @@ export class OperationsRepository implements IOperationsRepository {
async updateOperation(data: ObjeniousOperationChange): Promise<Result<string, ObjeniousOperation>> {
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<ObjeniousOperation>(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<ObjeniousOperation>(
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 <Result<string, ObjeniousOperation>>{
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 <Result<string, ObjeniousOperation>>{
data: undefined,

View File

@@ -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<string>(iccids)
console.log("iccidSet", iccidSet)
const req = this.httpClient.client.get<Objenious.ResponseGetMassAction[]>(PATH, {
params: <Objenious.ParametersGetMassAction>{
"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<Objenious.ResponseGetMassAction>(PATH + originalAction.mass_action_id, {
params: <Objenious.ParametersGetMassAction>{
}
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<string, StatusEnum>([
["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;
}