Merge main -> migracion alai
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
# claves de Objenious
|
||||
HOST=0.0.0.0
|
||||
|
||||
OBJ_PEM_PATH=./obj.pem
|
||||
OBJ_AUTHORIZATION=XOc7FtwXD8hUX2SFVX94XSty8wkOmChkwDNF09O_aIxPubMDdFUdCDCB4zpzSIxi8nOcTg7r_LM_nmd5qm7uLbksf_XArjI8iAyhjKz_2BAXPhmvKs4Fc9f3vv5LDfCVrPB9lP8P7rJ66_qnWs4jvhLQxSfn29m96hgXeCf8oySdIDUjN2q9Js3KAS5LL52Ri6ryvUeO1PvMhaPQMWRqoHIqTV1wPfPtiqQwcjUPmu5GeW164Kq1JLgV3KaGzfCZ9Qv9lbv30EJrukXxWuLCAhBS0kzrBXZoWvf2pb9uh3Am_93_dDxiIGQfIap9ZU_m8ZD1HPgvZOMCY6ZkxQconQ
|
||||
OBJ_CLI_ASSERTION=XOc7FtwXD8hUX2SFVX94XSty8wkOmChkwDNF09O_aIxPubMDdFUdCDCB4zpzSIxi8nOcTg7r_LM_nmd5qm7uLbksf_XArjI8iAyhjKz_2BAXPhmvKs4Fc9f3vv5LDfCVrPB9lP8P7rJ66_qnWs4jvhLQxSfn29m96hgXeCf8oySdIDUjN2q9Js3KAS5LL52Ri6ryvUeO1PvMhaPQMWRqoHIqTV1wPfPtiqQwcjUPmu5GeW164Kq1JLgV3KaGzfCZ9Qv9lbv30EJrukXxWuLCAhBS0kzrBXZoWvf2pb9uh3Am_93_dDxiIGQfIap9ZU_m8ZD1HPgvZOMCY6ZkxQconQ
|
||||
|
||||
@@ -10,6 +10,7 @@ import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js";
|
||||
import { PauseCancelTaskRepository } from "#adapters/PauseCancelTaskRepository.js";
|
||||
import { ObjeniousOperationsRepository } from "sim-shared/infrastructure/ObjeniousOperationRepository.js";
|
||||
import { ActionData } from "#domain/DTOs/objeniousapi.js";
|
||||
import { ObjeniousLinesRepository } from "sim-shared/infrastructure/ObjeniousLinesRepository.js";
|
||||
|
||||
describe("SimController Integration Tests (Real UseCases)", () => {
|
||||
let eventBusMock: any;
|
||||
@@ -32,11 +33,13 @@ describe("SimController Integration Tests (Real UseCases)", () => {
|
||||
);
|
||||
const orderRepository = new OrderRepository(postgrClient);
|
||||
const pauseRepository = new PauseCancelTaskRepository(postgrClient);
|
||||
const linesRepository = new ObjeniousLinesRepository(postgrClient) // tiene que apuntar a "intranet"
|
||||
useCases = new SimUseCases({
|
||||
httpClient: httpInstance,
|
||||
operationRepository: operationRepository,
|
||||
orderRepository: orderRepository,
|
||||
pauseRepository: pauseRepository
|
||||
pauseRepository: pauseRepository,
|
||||
objeniousLinesRepository: linesRepository
|
||||
});
|
||||
// @ts-expect-error
|
||||
useCases.findActivationDate = async (data: ActionData) => new Date()
|
||||
|
||||
@@ -4,6 +4,9 @@ import { SimUseCases } from "./Sim.usecases.js";
|
||||
import { SimEvents } from "sim-shared/domain/SimEvents.js";
|
||||
import { Result } from "sim-shared/domain/Result.js";
|
||||
import { ActionData } from "#domain/DTOs/objeniousapi.js";
|
||||
import { Request, Response } from "express"
|
||||
import { PaginationArgs, QueryPaginationArgs } from "sim-shared/domain/PaginationArgs.js";
|
||||
import { paginationValidator } from "./httpValidators.js";
|
||||
|
||||
/**
|
||||
* La clase usa generadores de funciones para mantener el contexto
|
||||
@@ -219,6 +222,36 @@ export class SimController {
|
||||
}
|
||||
}
|
||||
|
||||
public queryLines() {
|
||||
const DEFAULT_LIMIT = 1000
|
||||
const DEFAULT_OFFSET = 0
|
||||
|
||||
return async (req: Request, res: Response) => {
|
||||
const queryParams = req.query
|
||||
|
||||
const paginationArgs: QueryPaginationArgs = {
|
||||
limit: queryParams.limit as string | undefined,
|
||||
offset: queryParams.offset as string | undefined
|
||||
}
|
||||
|
||||
const validationRes = paginationValidator.validate(paginationArgs)
|
||||
if (validationRes.error != undefined) {
|
||||
res.status(402).json(validationRes)
|
||||
return;
|
||||
}
|
||||
|
||||
const paginationValues = {
|
||||
limit: (queryParams.limit != undefined) ? Number(queryParams.limit) : DEFAULT_LIMIT,
|
||||
offset: (queryParams.offset != undefined) ? Number(queryParams.offset) : DEFAULT_OFFSET
|
||||
}
|
||||
|
||||
const status = req.query.status
|
||||
|
||||
const queryRes = await this.useCases.getLinesByQuery({ status: status as string | undefined }, paginationValues)
|
||||
res.json(queryRes)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* - Loguear motivos de la no validacion
|
||||
|
||||
@@ -7,6 +7,9 @@ import assert from "node:assert"
|
||||
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
|
||||
import { CreatePauseCancelTaskDTO, PauseCancelTaskRepository } from "#adapters/PauseCancelTaskRepository.js"
|
||||
import { ObjeniousOperationsRepository } from "sim-shared/infrastructure/ObjeniousOperationRepository.js"
|
||||
import { ObjeniousLinesRepository } from "sim-shared/infrastructure/ObjeniousLinesRepository.js"
|
||||
import { error } from "node:console"
|
||||
import { ObjeniousLine, ObjeniousLineDb } from "sim-shared/domain/objeniousLine.js"
|
||||
|
||||
// TODO:
|
||||
// - Pasar a un archivo de DTOs
|
||||
@@ -17,17 +20,19 @@ export class SimUseCases {
|
||||
private readonly objeniousRepository: ObjeniousOperationsRepository
|
||||
private readonly orderRepository: OrderRepository
|
||||
private readonly pauseRepository: PauseCancelTaskRepository
|
||||
|
||||
private readonly objeniousLinesRepository: ObjeniousLinesRepository
|
||||
constructor(args: {
|
||||
httpClient: HttpClient,
|
||||
operationRepository: ObjeniousOperationsRepository,
|
||||
orderRepository: OrderRepository,
|
||||
pauseRepository: PauseCancelTaskRepository
|
||||
pauseRepository: PauseCancelTaskRepository,
|
||||
objeniousLinesRepository: ObjeniousLinesRepository
|
||||
}) {
|
||||
this.httpClient = args.httpClient
|
||||
this.objeniousRepository = args.operationRepository
|
||||
this.orderRepository = args.orderRepository
|
||||
this.pauseRepository = args.pauseRepository
|
||||
this.objeniousLinesRepository = args.objeniousLinesRepository
|
||||
}
|
||||
|
||||
private async logOperation(data: ObjeniousOperation) {
|
||||
@@ -119,7 +124,6 @@ export class SimUseCases {
|
||||
const iccid = activationData.identifier.identifiers
|
||||
// Comporbación excepcional para saber si la linea está suspendida
|
||||
const statusLinea = await this.objeniousRepository.getLinesAPI("ICCID", [String(iccid)])
|
||||
console.log("statusLinea, ", iccid, statusLinea)
|
||||
if (statusLinea.data != undefined && statusLinea.data[0].status.networkStatus == "SUSPENDED") {
|
||||
const res = await this.reActivate(activationData)()
|
||||
return res;
|
||||
@@ -269,7 +273,7 @@ export class SimUseCases {
|
||||
|
||||
/**
|
||||
* Metodo muy especifico para obtener la fecha e activacion o en su defecto
|
||||
* la actual para aber cuando se va a completar el periodo de test de una linea
|
||||
* la actual para saber cuando se va a completar el periodo de test de una linea
|
||||
*/
|
||||
private async findActivationDate(actionData: ActionData) {
|
||||
const iccid = actionData.identifier.identifiers
|
||||
@@ -278,7 +282,7 @@ export class SimUseCases {
|
||||
// Si no se pueden sacar datos de la linea guardo momentaneamente el error
|
||||
// pero no se cancela la operacion, el error puede ser de objenious y no nos
|
||||
// puede afectar
|
||||
console.log("LineData", lineData.data)
|
||||
//console.log("LineData", lineData.data)
|
||||
if (lineData.error != undefined) {
|
||||
console.error(lineData.error)
|
||||
} else {
|
||||
@@ -321,13 +325,14 @@ export class SimUseCases {
|
||||
}
|
||||
|
||||
// TODO REGISTRAR EL ORDER
|
||||
/*
|
||||
if (correlation_id != undefined) {
|
||||
await this.orderRepository.createOrder({
|
||||
correlation_id: correlation_id,
|
||||
order_type: "pause"
|
||||
})
|
||||
}
|
||||
|
||||
*/
|
||||
let activationDate;
|
||||
try {
|
||||
activationDate = await this.findActivationDate(suspendData)
|
||||
@@ -434,10 +439,53 @@ export class SimUseCases {
|
||||
identifier: terminationData.identifier
|
||||
},
|
||||
url: OPERATION_URL,
|
||||
iccid: terminationData.identifier.identifiers[0], //
|
||||
iccid: terminationData.identifier.identifiers[0],
|
||||
operation: "terminate"
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcula el tiempo que una linea ha estado en suspensión
|
||||
*/
|
||||
public async getSuspendedTime(iccid: string):
|
||||
Promise<Result<string, { total_milliseconds: number, total_days: number }>> {
|
||||
try {
|
||||
const result = await this.objeniousRepository.getSuspendedTime(iccid);
|
||||
if (result.error !== undefined) {
|
||||
return { error: result.error as string, data: undefined };
|
||||
}
|
||||
return {
|
||||
data: {
|
||||
total_milliseconds: result.data!.total_milliseconds,
|
||||
total_days: result.data!.total_days
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("[Sim.usecases] Error getting suspended time", error);
|
||||
return { error: "Error getting suspended time", data: undefined };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Busqueda de líneas **en nuestro volcado** según una query y con paginacion
|
||||
*/
|
||||
public async getLinesByQuery(query: { status?: string | undefined }, pagination: { limit: number, offset: number })
|
||||
: Promise<Result<string, {
|
||||
data: ObjeniousLineDb[],
|
||||
offset: number,
|
||||
rowCount: number
|
||||
}>> {
|
||||
try {
|
||||
|
||||
const linesQuery = await this.objeniousLinesRepository.getLinesByStatus(query, pagination)
|
||||
return {
|
||||
data: linesQuery,
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
error: String(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { BodyValidator, Validator } from "sim-shared/aplication/BodyValidator.js";
|
||||
import { QueryPaginationArgs } from "sim-shared/domain/PaginationArgs.js";
|
||||
|
||||
const limitPositiveOrUndefined = <Validator<QueryPaginationArgs>>{
|
||||
field: "limit",
|
||||
validationFunc: (args) => (args.limit == undefined || !isNaN(+args.limit) && parseInt(args.limit) >= 0),
|
||||
errorMsg: "El campo limit debe ser un numero o undefined (default 0)"
|
||||
}
|
||||
const offsetPositiveOrUndefined = <Validator<QueryPaginationArgs>>{
|
||||
field: "offset",
|
||||
validationFunc: (args) => (args.offset == undefined || isNaN(+args.offset) && parseInt(args.offset) >= 1),
|
||||
errorMsg: "El campo offset debe ser un numero o undefined (default 0)"
|
||||
}
|
||||
|
||||
export const paginationValidator = new BodyValidator<QueryPaginationArgs & {}>([
|
||||
limitPositiveOrUndefined,
|
||||
offsetPositiveOrUndefined
|
||||
])
|
||||
@@ -4,7 +4,10 @@ import path from "node:path";
|
||||
loadEnvFile(path.join("../../.env")) // Global
|
||||
loadEnvFile(path.join("./.env")) // base
|
||||
|
||||
|
||||
export const env = {
|
||||
PORT: parseInt(process.env.OBJENIOUS_CONSUMER_PORT || "3002"),
|
||||
|
||||
ENVIRONMENT: process.env.ENVIORMENT,
|
||||
POSTGRES_USER: process.env.POSTGRES_USER,
|
||||
POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Cliente de postgres para la intranet. Se usa solo porque hace falta para el
|
||||
* volcado de datos, si se usa en mas partes algo estás haciendo mal.
|
||||
*/
|
||||
|
||||
import { Pool } from 'pg';
|
||||
import { PgClient } from 'sim-shared/infrastructure/PgClient.js'
|
||||
import { env } from './env/index.js';
|
||||
|
||||
export const pgPoolIntranet = new Pool({
|
||||
user: env.POSTGRES_USER,
|
||||
host: env.POSTGRES_HOST,
|
||||
database: "intranet",
|
||||
password: env.POSTGRES_PASSWORD,
|
||||
port: Number(env.POSTGRES_PORT) || 5432,
|
||||
});
|
||||
|
||||
export const postgresClientIntranet = new PgClient({
|
||||
pool: pgPoolIntranet
|
||||
})
|
||||
@@ -10,6 +10,13 @@ import { SimRouter } from "./aplication/Sim.router.js"
|
||||
import { OrderRepository } from "sim-shared/infrastructure/OrderRepository.js"
|
||||
import { PauseCancelTaskRepository } from "#adapters/PauseCancelTaskRepository.js"
|
||||
|
||||
import express from "express"
|
||||
import cors from "cors"
|
||||
import assert from "node:assert";
|
||||
import { env } from "#config/env/index.js"
|
||||
import { ObjeniousLinesRepository } from "sim-shared/infrastructure/ObjeniousLinesRepository.js"
|
||||
import { postgresClientIntranet } from "#config/intranetPostgresConfig.js"
|
||||
|
||||
async function startWorker() {
|
||||
const rmqClient = await startRMQClient()
|
||||
|
||||
@@ -26,20 +33,76 @@ async function startWorker() {
|
||||
const orderRepository = new OrderRepository(pgClient)
|
||||
|
||||
const pauseRepository = new PauseCancelTaskRepository(pgClient)
|
||||
|
||||
const simActivationController = new SimController(
|
||||
rmqClient,
|
||||
new SimUseCases({
|
||||
httpClient: httpClient,
|
||||
operationRepository: operationRepository,
|
||||
orderRepository: orderRepository,
|
||||
pauseRepository: pauseRepository
|
||||
})
|
||||
const linesRepository = new ObjeniousLinesRepository(
|
||||
postgresClientIntranet
|
||||
)
|
||||
const simRouter = new SimRouter(simActivationController, rmqClient)
|
||||
|
||||
const simUseCases = new SimUseCases({
|
||||
httpClient: httpClient,
|
||||
operationRepository: operationRepository,
|
||||
orderRepository: orderRepository,
|
||||
pauseRepository: pauseRepository,
|
||||
objeniousLinesRepository: linesRepository
|
||||
})
|
||||
|
||||
const simController = new SimController(
|
||||
rmqClient,
|
||||
simUseCases
|
||||
)
|
||||
const simRouter = new SimRouter(simController, rmqClient)
|
||||
|
||||
// de momento solo una cola por simplificar
|
||||
rmqClient.consume("sim.objenious", simRouter.route)
|
||||
|
||||
// Servidor express
|
||||
const port = env.PORT
|
||||
const app = express()
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
|
||||
app.get("/health", async (req, res) => {
|
||||
res.json({ ok: "true" })
|
||||
})
|
||||
|
||||
// TODO: meter el template de controller con los validadores
|
||||
app.get("/lines/:iccid/suspended-time", async (req, res) => {
|
||||
const iccid = req.params.iccid
|
||||
if (!iccid) {
|
||||
res.status(400).json({ error: "iccid is required" })
|
||||
return
|
||||
}
|
||||
|
||||
const result = await simUseCases.getSuspendedTime(iccid)
|
||||
if (result.error !== undefined) {
|
||||
res.status(500).json({ error: result.error })
|
||||
return
|
||||
}
|
||||
|
||||
res.json(result) // {data:{...}} || {error:{...}}
|
||||
})
|
||||
|
||||
/**
|
||||
* Opciones query:
|
||||
* - state
|
||||
*
|
||||
* Respuestas:
|
||||
* - OK: data: {
|
||||
* lines: ObjeniousLineDb[],
|
||||
* offset: number,
|
||||
* rowCount: number
|
||||
* }
|
||||
*
|
||||
* - ERR: error: {
|
||||
* message: string
|
||||
* }
|
||||
*/
|
||||
app.get("/lines", simController.queryLines())
|
||||
|
||||
|
||||
assert.ok(port, "Puerto del servicio no definido")
|
||||
app.listen(port, () => {
|
||||
console.log(`[o] HTTP server listening on port ${port}`)
|
||||
})
|
||||
}
|
||||
|
||||
startWorker()
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
"types": "./config/*.ts",
|
||||
"default": "./config/*.js"
|
||||
},
|
||||
"#shared/*.js": {
|
||||
"sim-shared/*.js": {
|
||||
"default": "../sim-shared/*.js"
|
||||
},
|
||||
"#shared/*": {
|
||||
"sim-shared/*": {
|
||||
"default": "../sim-shared/*.js"
|
||||
},
|
||||
"#adapters/*.js": {
|
||||
|
||||
Reference in New Issue
Block a user