Orders en todas las etapas
This commit is contained in:
@@ -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;
|
||||
@@ -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<Result<string, boolean>> {
|
||||
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 <Result<string, boolean>>{
|
||||
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<Result<string, boolean>> {
|
||||
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 <Result<string, boolean>>{
|
||||
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 <Result<string, boolean>>{
|
||||
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"
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<OrderTracking<any>>(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)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user