42 Commits

Author SHA1 Message Date
8a53fb6749 iccid en lista 2026-02-12 09:41:00 +01:00
3a55e5f057 Caracteres de escaoe en el iccid 2026-02-12 08:56:11 +01:00
6bc1340930 operation 2026-02-11 20:24:33 +01:00
2299d5f735 Body 2026-02-11 20:08:22 +01:00
e454a3fee1 url 2026-02-11 19:56:46 +01:00
672de92e5b Fix url 2026-02-11 19:53:55 +01:00
404f142c7e Inicio del cron 2026-02-11 19:46:33 +01:00
8fcf592b88 URLURL 2026-02-11 19:43:54 +01:00
d91e7e746c Config 2026-02-11 19:34:31 +01:00
f176788267 Created deployment 2026-02-11 18:53:40 +01:00
c4721328f8 Created deployment 2026-02-11 18:52:12 +01:00
e878c9a27e Created deployment 2026-02-11 18:41:02 +01:00
d17e399a4c Created deployment 2026-02-11 18:21:49 +01:00
068ec20a9b Merge branch 'main' of git.savefamilygps.net:SaveFamily/sf-sim 2026-02-11 18:11:13 +01:00
b32e1af71c error env 2026-02-11 18:11:10 +01:00
fe5b492218 Error de la ruta de env 2026-02-11 18:10:39 +01:00
a217914ec6 Created deployment 2026-02-11 18:07:54 +01:00
669abd3c43 Created deployment 2026-02-11 17:59:46 +01:00
43cef09f89 Created deployment 2026-02-11 17:56:40 +01:00
0a9470b1d8 Created deployment 2026-02-11 17:52:22 +01:00
6c6916c4cb Created deployment 2026-02-11 17:48:29 +01:00
39f8708fca Created deployment 2026-02-11 17:46:01 +01:00
4df80f6171 Created deployment 2026-02-11 17:45:36 +01:00
5296f58cef Created deployment 2026-02-11 17:44:44 +01:00
ecd5190713 Merge branch 'main' of git.savefamilygps.net:SaveFamily/sf-sim 2026-02-11 17:25:18 +01:00
71e0ec959c Vuelta atras del entrypoint 2026-02-11 17:24:28 +01:00
c40876af77 Merge branch 'main' of git.savefamilygps.net:SaveFamily/sf-sim 2026-02-11 17:12:51 +01:00
1888b82425 Created deployment 2026-02-11 17:11:23 +01:00
54e670cb87 Errata 2026-02-11 17:09:23 +01:00
166abf8b16 Error de tipado 2026-02-11 15:41:03 +01:00
4a58595870 ñadir numero en la respuesta de las activaciones 2026-02-11 15:14:15 +01:00
261342a629 Prueba despliegue 2026-02-11 13:41:45 +01:00
4d778e96ea Problema de despliegue 2026-02-11 13:29:46 +01:00
05ea4e76cc Notificacion cuando finalice una activacion 2026-02-11 13:20:04 +01:00
61c91b6548 Created deployment 2026-02-11 11:33:12 +01:00
2d926d2583 Created deployment 2026-02-10 17:51:44 +01:00
25bc40840e Created deployment 2026-02-10 17:47:15 +01:00
aed7624e1e Created deployment 2026-02-10 17:43:31 +01:00
3ce820ef64 Created deployment 2026-02-10 17:39:45 +01:00
b86e6c6066 Created deployment 2026-02-10 17:27:05 +01:00
d90f5af0d7 Created deployment 2026-02-10 17:25:01 +01:00
97c9ffaf77 Created deployment 2026-02-10 17:16:29 +01:00
19 changed files with 322 additions and 79 deletions

View File

@@ -1,10 +1,22 @@
# --- Release image --- # --- Release image ---
FROM node:22-alpine AS release FROM node:22-alpine AS release
ARG PORT
WORKDIR /home/node/app WORKDIR /home/node/app
COPY ./dist/src ./src
COPY ./dist/package.json ./ RUN corepack enable
COPY ./dist/package-lock.json ./
RUN npm ci COPY ./dist/packages ./packages
EXPOSE $PORT
ENTRYPOINT ["node", "src/apps/index.js"] COPY ./package.json ./
# Force node-modules linker (no .yarnrc.yml in build context)
RUN echo 'nodeLinker: node-modules' > .yarnrc.yml
RUN yarn install
RUN mkdir -p dist && ln -sf ../packages dist/packages
COPY ./entrypoint.sh ./
RUN chmod +x entrypoint.sh
EXPOSE ${PORT:-3000}
ENTRYPOINT ["./entrypoint.sh"]

View File

@@ -4,6 +4,8 @@ networks:
external: true external: true
proxy: proxy:
external: true external: true
internal:
driver: bridge
services: services:
rabbitmq-sim-broker: rabbitmq-sim-broker:
@@ -21,14 +23,32 @@ services:
timeout: 5s timeout: 5s
retries: 5 retries: 5
environment: environment:
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER} RABBITMQ_USER: ${RABBITMQ_USER}
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD} RABBITMQ_PASSWORD: ${RABBITMQ_PASSWORD}
entrypoint: ["bash", "/usr/local/bin/docker-entrypoint-wrapper.sh"]
command: ["rabbitmq-server"]
volumes: volumes:
- ./rabbit/docker-entrypoint-wrapper.sh:/usr/local/bin/docker-entrypoint-wrapper.sh:ro
- ./rabbitmq_plugins/enabled_plugins:/etc/rabbitmq/enabled_plugins:ro - ./rabbitmq_plugins/enabled_plugins:/etc/rabbitmq/enabled_plugins:ro
- ./rabbit/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro - ./rabbit/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf:ro
- ./rabbit/definitions.json:/etc/rabbitmq/definitions.json:ro - ./rabbit/definitions.json:/etc/rabbitmq/definitions.template.json:ro
networks:
- internal
- proxy
labels: labels:
- "io.portainer.accesscontrol.teams=develop" - "io.portainer.accesscontrol.teams=develop"
- "traefik.enable=true"
- "traefik.http.routers.sf-sims-rabbitmq.entrypoints=web"
- "traefik.http.routers.sf-sims-rabbitmq.rule=Host(`sf-sims-rabbitmq.savefamilygps.net`)"
- "traefik.http.middlewares.sf-sims-rabbitmq-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.sf-sims-rabbitmq.middlewares=sf-sims-rabbitmq-https-redirect"
- "traefik.http.routers.sf-sims-rabbitmq-secure.entrypoints=websecure"
- "traefik.http.routers.sf-sims-rabbitmq-secure.rule=Host(`sf-sims-rabbitmq.savefamilygps.net`)"
- "traefik.http.routers.sf-sims-rabbitmq-secure.tls=true"
- "traefik.http.routers.sf-sims-rabbitmq-secure.service=sf-sims-rabbitmq"
- "traefik.http.routers.sf-sims-rabbitmq-secure.tls.certresolver=myresolver"
- "traefik.http.services.sf-sims-rabbitmq.loadbalancer.server.port=15672"
- "traefik.docker.network=proxy"
sf-sims-api: sf-sims-api:
container_name: sf-sims-api container_name: sf-sims-api
@@ -44,13 +64,28 @@ services:
depends_on: depends_on:
rabbitmq-sim-broker: rabbitmq-sim-broker:
condition: service_healthy condition: service_healthy
postgresql-sim:
condition: service_healthy
networks: networks:
- savefamily - savefamily
- proxy - proxy
- internal
expose: expose:
- ${PORT} - ${PORT}
volumes:
- ./.env:/home/node/app/.env:ro
- ./sim-consumidor-objenious.env:/home/node/app/packages/sim-consumidor-objenious/.env:ro
- ./sim-objenious-cron.env:/home/node/app/packages/sim-objenious-cron/.env:ro
- ./obj.pem:/home/node/app/packages/sim-consumidor-objenious/obj.pem:ro
- ./obj.pem:/home/node/app/packages/sim-objenious-cron/obj.pem:ro
healthcheck:
test:
[
"CMD-SHELL",
'node -e "fetch(''http://localhost:'' + (process.env.PORT || 3000) + ''/health'').then(r => { if (!r.ok) process.exit(1) }).catch(() => process.exit(1))"',
]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
labels: labels:
- "io.portainer.accesscontrol.teams=develop" - "io.portainer.accesscontrol.teams=develop"
- "traefik.enable=true" - "traefik.enable=true"
@@ -63,24 +98,5 @@ services:
- "traefik.http.routers.sf-sims-secure.tls=true" - "traefik.http.routers.sf-sims-secure.tls=true"
- "traefik.http.routers.sf-sims-secure.service=sf-sims" - "traefik.http.routers.sf-sims-secure.service=sf-sims"
- "traefik.http.routers.sf-sims-secure.tls.certresolver=myresolver" - "traefik.http.routers.sf-sims-secure.tls.certresolver=myresolver"
- "traefik.http.routers.sf-sims-secure.middlewares=tailscale-ipwhitelist@file"
- "traefik.http.services.sf-sims.loadbalancer.server.port=${PORT}" - "traefik.http.services.sf-sims.loadbalancer.server.port=${PORT}"
- "traefik.docker.network=proxy" - "traefik.docker.network=proxy"
postgresql-sim:
image: postgres:16.1
env_file:
- ./.env
ports:
- 5432
volumes:
- ./postgres:/var/lib/postgres/data
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
retries: 5
start_period: 5s
timeout: 5s
labels:
- "io.portainer.accesscontrol.teams=develop"

View File

@@ -0,0 +1,4 @@
#!/bin/sh
cd /home
cd /home/node/app && yarn start

View File

@@ -16,12 +16,13 @@ pipeline {
steps { steps {
sh 'npm install -g yarn' sh 'npm install -g yarn'
sh 'corepack enable' sh 'corepack enable'
sh 'corepack prepare yarn@3.2.1 --activate' sh 'corepack prepare yarn@4.12.0 --activate'
sh 'yarn install --immutable' sh 'yarn install --immutable'
} }
} }
stage("🧱 Building") { stage("🧱 Building") {
steps { steps {
sh 'rm -rf dist/'
sh 'yarn run build' sh 'yarn run build'
} }
} }
@@ -41,12 +42,24 @@ pipeline {
cleanRemote: false, cleanRemote: false,
execCommand: "ln -sf $BASE_REMOTE_PATH/vault/savefamily/sf-sims/.env $APP_REMOTE_PATH/.env" execCommand: "ln -sf $BASE_REMOTE_PATH/vault/savefamily/sf-sims/.env $APP_REMOTE_PATH/.env"
), ),
sshTransfer(
cleanRemote: false,
execCommand: "ln -sf $BASE_REMOTE_PATH/vault/savefamily/sf-sims/sim-consumidor-objenious.env $APP_REMOTE_PATH/sim-consumidor-objenious.env"
),
sshTransfer(
cleanRemote: false,
execCommand: "ln -sf $BASE_REMOTE_PATH/vault/savefamily/sf-sims/sim-objenious-cron.env $APP_REMOTE_PATH/sim-objenious-cron.env"
),
sshTransfer(
cleanRemote: false,
execCommand: "ln -sf $BASE_REMOTE_PATH/vault/savefamily/sf-sims/obj.pem $APP_REMOTE_PATH/obj.pem"
),
sshTransfer( sshTransfer(
cleanRemote: false, cleanRemote: false,
remoteDirectory: "$APP_REMOTE_PATH", remoteDirectory: "$APP_REMOTE_PATH",
sourceFiles: "dist/**/*", sourceFiles: "dist/**/*",
excludes: "dist/**/node_modules/**" excludes: "dist/**/node_modules/**"
), ),
sshTransfer( sshTransfer(
cleanRemote: false, cleanRemote: false,
remoteDirectory: "$APP_REMOTE_PATH", remoteDirectory: "$APP_REMOTE_PATH",
@@ -56,8 +69,8 @@ pipeline {
sshTransfer( sshTransfer(
cleanRemote: false, cleanRemote: false,
remoteDirectory: "$APP_REMOTE_PATH", remoteDirectory: "$APP_REMOTE_PATH",
sourceFiles: "deployment/rabbit/**/*", sourceFiles: "deployment/develop/rabbit/**/*",
removePrefix: "deployment", removePrefix: "deployment/develop",
), ),
sshTransfer( sshTransfer(
cleanRemote: false, cleanRemote: false,
@@ -70,22 +83,11 @@ pipeline {
sourceFiles: "deployment/develop/docker/**/*", sourceFiles: "deployment/develop/docker/**/*",
removePrefix: "deployment/develop/docker", removePrefix: "deployment/develop/docker",
), ),
sshTransfer(
cleanRemote: false,
remoteDirectory: "$APP_REMOTE_PATH",
sourceFiles: "deployment/Dockerfile",
removePrefix: "deployment",
),
sshTransfer( sshTransfer(
cleanRemote: false, cleanRemote: false,
remoteDirectory: "$APP_REMOTE_PATH", remoteDirectory: "$APP_REMOTE_PATH",
sourceFiles: "package.json", sourceFiles: "package.json",
), ),
sshTransfer(
cleanRemote: false,
remoteDirectory: "$APP_REMOTE_PATH",
sourceFiles: "package-lock.json",
),
sshTransfer( sshTransfer(
cleanRemote: false, cleanRemote: false,
execCommand: "sh $APP_REMOTE_PATH/rebuild.sh" execCommand: "sh $APP_REMOTE_PATH/rebuild.sh"

View File

@@ -0,0 +1,90 @@
{
"rabbit_version": "4.2.2",
"rabbitmq_version": "4.2.2",
"product_name": "RabbitMQ",
"product_version": "4.2.2",
"users": [
{
"name": "RABBITMQ_USER_PLACEHOLDER",
"password": "RABBITMQ_PASSWORD_PLACEHOLDER",
"tags": ["administrator"]
}
],
"vhosts": [
{
"name": "sim-vhost"
}
],
"permissions": [
{
"user": "RABBITMQ_USER_PLACEHOLDER",
"vhost": "sim-vhost",
"configure": ".*",
"write": ".*",
"read": ".*"
}
],
"topic_permissions": [],
"parameters": [],
"global_parameters": [
{
"name": "cluster_name",
"value": "rabbit@a8d5c6e08439"
},
{
"name": "internal_cluster_id",
"value": "rabbitmq-cluster-id-gXeBLbsUC2W2tU0Bx_QY_w"
}
],
"policies": [
{
"vhost": "sim-vhost",
"name": "pol.sim.dlx",
"pattern": "sim.*",
"apply-to": "queues",
"definition": {
"dead-letter-exchange": "sim.dlx"
},
"priority": 7
}
],
"exchanges": [
{
"name": "sim.exchange",
"vhost": "sim-vhost",
"type": "topic",
"durable": true,
"auto_delete": false,
"internal": false,
"argurments": {}
},
{
"name": "sim.dlx",
"vhost": "sim-vhost",
"type": "topic",
"durable": true,
"auto_delete": false,
"internal": false,
"argurments": {}
}
],
"queues": [
{
"name": "sim.logs",
"vhost": "sim-vhost",
"durable": true,
"auto_delete": false,
"arguments": {}
}
],
"bindings": [
{
"source": "sim.exchange",
"vhost": "sim-vhost",
"destination": "sim.logs",
"destination_type": "queue",
"routing_key": "sim.#",
"arguments": {}
}
]
}

View File

@@ -0,0 +1,12 @@
#!/bin/bash
set -eu
# Substitute env vars into definitions template before RabbitMQ starts.
# RabbitMQ 4.x skips default user creation when definitions.json is loaded,
# so the user must be defined in the JSON itself.
sed \
-e "s|RABBITMQ_USER_PLACEHOLDER|${RABBITMQ_USER}|g" \
-e "s|RABBITMQ_PASSWORD_PLACEHOLDER|${RABBITMQ_PASSWORD}|g" \
/etc/rabbitmq/definitions.template.json > /etc/rabbitmq/definitions.json
exec docker-entrypoint.sh "$@"

View File

@@ -0,0 +1,4 @@
management.load_definitions = /etc/rabbitmq/definitions.json
default_vhost = sim-vhost
default_queue_type = quorum

View File

@@ -0,0 +1,3 @@
vars {
baseurl: https://sf-sims.savefamilygps.net
}

View File

@@ -0,0 +1,33 @@
meta {
name: Unit action by id copy
type: http
seq: 19
}
get {
url: https://api-getway.objenious.com/ws/actions/massActions/{{id}}
body: formUrlEncoded
auth: bearer
}
auth:bearer {
token: {{ws-access-token-partenaire}}
}
body:json {
{
"identifier": {
"identifiers": ["8933201124059175967"],
"identifierType": "ICCID"
}
}
}
vars:pre-request {
id: 5192767
}
settings {
encodeUrl: true
timeout: 0
}

View File

@@ -9,8 +9,8 @@ export const env = {
POSTGRES_HOST: process.env.POSTGRES_HOST, POSTGRES_HOST: process.env.POSTGRES_HOST,
POSTGRES_DATABASE: process.env.POSTGRES_DATABASE, POSTGRES_DATABASE: process.env.POSTGRES_DATABASE,
RABBITMQ_HOST: String(process.env.RABBITMQ_HOST ?? "localhost"), RABBITMQ_HOST: String(process.env.RABBITMQ_HOST ?? "localhost"),
RABBITMQ_USER: String(process.env.RABBITMQ_USER ?? "guest"), RABBITMQ_USER: String(process.env.RABBITMQ_USER ?? "test"),
RABBITMQ_PASSWORD: String(process.env.RABBITMQ_PASSWORD ?? "guest"), RABBITMQ_PASSWORD: String(process.env.RABBITMQ_PASSWORD ?? "test"),
RABBITMQ_EXCHANGE: String(process.env.RABBITMQ_EXCHANGE ?? "/"), RABBITMQ_EXCHANGE: String(process.env.RABBITMQ_EXCHANGE ?? "/"),
RABBITMQ_PORT: parseInt(process.env.RABBITMQ_PORT ?? "5672"), RABBITMQ_PORT: parseInt(process.env.RABBITMQ_PORT ?? "5672"),
RABBITMQ_MODULENAME: process.env.MODULENAME, RABBITMQ_MODULENAME: process.env.MODULENAME,

View File

@@ -8,7 +8,6 @@ import { ObjeniousOperation, IOperationsRepository as OperationsRepositoryPort }
// - Pasar a un archivo de DTOs // - Pasar a un archivo de DTOs
// - Mucha repeticion por funcion, deberia hacer una plantilla // - Mucha repeticion por funcion, deberia hacer una plantilla
export class SimUseCases { export class SimUseCases {
private readonly httpClient: HttpClient private readonly httpClient: HttpClient
private readonly operationRepository: OperationsRepositoryPort private readonly operationRepository: OperationsRepositoryPort
@@ -41,7 +40,7 @@ export class SimUseCases {
const operation: ObjeniousOperation = { const operation: ObjeniousOperation = {
operation: "activate", operation: "activate",
iccids: activationData.identifier.identifiers, iccids: String(activationData.identifier.identifiers),
status: "noMassID", status: "noMassID",
request_id: response.data.requestId request_id: response.data.requestId
} }
@@ -84,7 +83,7 @@ export class SimUseCases {
console.log("Sim preactivada con exito", resp.data) console.log("Sim preactivada con exito", resp.data)
const operation: ObjeniousOperation = { const operation: ObjeniousOperation = {
operation: "preActivate", operation: "preActivate",
iccids: preActivateData.identifier.identifiers, iccids: String(preActivateData.identifier.identifiers),
status: "noMassID", status: "noMassID",
request_id: resp.data.requestId request_id: resp.data.requestId
} }

View File

@@ -12,8 +12,8 @@ export const env = {
POSTGRES_HOST: process.env.POSTGRES_HOST, POSTGRES_HOST: process.env.POSTGRES_HOST,
POSTGRES_DATABASE: process.env.POSTGRES_DATABASE, POSTGRES_DATABASE: process.env.POSTGRES_DATABASE,
RABBITMQ_HOST: String(process.env.RABBITMQ_HOST ?? "localhost"), RABBITMQ_HOST: String(process.env.RABBITMQ_HOST ?? "localhost"),
RABBITMQ_USER: String(process.env.RABBITMQ_USER ?? "guest"), RABBITMQ_USER: String(process.env.RABBITMQ_USER ?? "test"),
RABBITMQ_PASSWORD: String(process.env.RABBITMQ_PASSWORD ?? "guest"), RABBITMQ_PASSWORD: String(process.env.RABBITMQ_PASSWORD ?? "test"),
RABBITMQ_EXCHANGE: String(process.env.RABBITMQ_EXCHANGE ?? "/"), RABBITMQ_EXCHANGE: String(process.env.RABBITMQ_EXCHANGE ?? "/"),
RABBITMQ_PORT: parseInt(process.env.RABBITMQ_PORT ?? "5672"), RABBITMQ_PORT: parseInt(process.env.RABBITMQ_PORT ?? "5672"),
RABBITMQ_MODULENAME: process.env.MODULENAME, RABBITMQ_MODULENAME: process.env.MODULENAME,

View File

@@ -1,7 +1,8 @@
import { loadEnvFile } from "node:process"; import { loadEnvFile } from "node:process";
import path from "node:path"; import path from "node:path";
loadEnvFile(path.join(import.meta.dirname, "../../../../.env"))
loadEnvFile(path.join("../../.env")) // Global
export const env = { export const env = {
ENVIRONMENT: process.env.ENVIORMENT, ENVIRONMENT: process.env.ENVIORMENT,
@@ -12,8 +13,8 @@ export const env = {
POSTGRES_HOST: process.env.POSTGRES_HOST, POSTGRES_HOST: process.env.POSTGRES_HOST,
POSTGRES_DATABASE: process.env.POSTGRES_DATABASE, POSTGRES_DATABASE: process.env.POSTGRES_DATABASE,
RABBITMQ_HOST: String(process.env.RABBITMQ_HOST ?? "localhost"), RABBITMQ_HOST: String(process.env.RABBITMQ_HOST ?? "localhost"),
RABBITMQ_USER: String(process.env.RABBITMQ_USER ?? "guest"), RABBITMQ_USER: String(process.env.RABBITMQ_USER ?? "test"),
RABBITMQ_PASSWORD: String(process.env.RABBITMQ_PASSWORD ?? "guest"), RABBITMQ_PASSWORD: String(process.env.RABBITMQ_PASSWORD ?? "test"),
RABBITMQ_EXCHANGE: String(process.env.RABBITMQ_EXCHANGE ?? "/"), RABBITMQ_EXCHANGE: String(process.env.RABBITMQ_EXCHANGE ?? "/"),
RABBITMQ_PORT: parseInt(process.env.RABBITMQ_PORT ?? "5672"), RABBITMQ_PORT: parseInt(process.env.RABBITMQ_PORT ?? "5672"),
RABBITMQ_MODULENAME: process.env.MODULENAME, RABBITMQ_MODULENAME: process.env.MODULENAME,

View File

@@ -6,3 +6,5 @@ OBJ_CLIENT_ID=savefamily_rest_ws
OBJ_KID=xNfbMiyL1ORXGP8lElhcv8nVaG3EJKye4Lc1YoN3I1E OBJ_KID=xNfbMiyL1ORXGP8lElhcv8nVaG3EJKye4Lc1YoN3I1E
OBJ_BASE_URL=https://api-getway.objenious.com/ws OBJ_BASE_URL=https://api-getway.objenious.com/ws
//OBJ_BASE_URL=https://api-getway.objenious.com/ws/test //OBJ_BASE_URL=https://api-getway.objenious.com/ws/test
NOTIFICATION_URL="https://sf-sim-activation.savefamilygps.net/send-activation-mail"

View File

@@ -28,7 +28,8 @@ export const env = {
OBJ_CLI_ASSERTION: String(process.env.OBJ_CLI_ASSERTION), OBJ_CLI_ASSERTION: String(process.env.OBJ_CLI_ASSERTION),
OBJ_CLIENT_ID: String(process.env.OBJ_CLIENT_ID), OBJ_CLIENT_ID: String(process.env.OBJ_CLIENT_ID),
OBJ_KID: String(process.env.OBJ_KID), OBJ_KID: String(process.env.OBJ_KID),
OBJ_BASE_URL: String(process.env.OBJ_BASE_URL) OBJ_BASE_URL: String(process.env.OBJ_BASE_URL),
NOTIFICATION_URL: String(process.env.NOTIFICATION_URL)
}; };

View File

@@ -22,6 +22,7 @@ async function startCron() {
httpClient httpClient
) )
await objTask.getPendingOperations()
const interval = setInterval(async () => { const interval = setInterval(async () => {
console.log("Updating...") console.log("Updating...")
await objTask.getPendingOperations() await objTask.getPendingOperations()

View File

@@ -1,3 +1,5 @@
import { env } from "#config/env/index.js";
import axios from "axios";
import { IOperationsRepository, Objenious, ObjeniousOperation, ObjeniousOperationChange, StatusEnum } from "sim-shared/domain/operationsRepository.port.js"; import { IOperationsRepository, Objenious, ObjeniousOperation, ObjeniousOperationChange, StatusEnum } from "sim-shared/domain/operationsRepository.port.js";
import { HttpClient } from "sim-shared/infrastructure/HTTPClient.js"; import { HttpClient } from "sim-shared/infrastructure/HTTPClient.js";
@@ -36,14 +38,13 @@ export class CheckObjeniousRequests {
const consultarEstado = pendingOperations.data const consultarEstado = pendingOperations.data
.filter(e => e.mass_action_id != undefined) .filter(e => e.mass_action_id != undefined)
console.log("validas", operacionesValidas) console.log("[cron] Solicitando mass id para", solicitarMassId.map(e => e.id))
console.log("Solicitando mass id para", solicitarMassId)
const newMassActions = await this.getMassIdFromRequest(solicitarMassId) const newMassActions = await this.getMassIdFromRequest(solicitarMassId)
const merged = [...newMassActions || [], ...consultarEstado] const merged = [...newMassActions || [], ...consultarEstado]
console.log("Solicitando status para", merged) console.log("[cron] Solicitando status para", merged.map(e => e.id))
const result = await this.getMassActionsStatus(merged) const result = await this.getMassActionsStatus(merged)
} }
@@ -55,16 +56,9 @@ export class CheckObjeniousRequests {
const PATH = "/actions/massActions/" const PATH = "/actions/massActions/"
const updated = [] const updated = []
const iccids = operationsList
.map(e => e.iccids)
.flat()
const mass_actions = operationsList const mass_actions = operationsList
.filter(e => e.mass_action_id != undefined) .filter(e => e.mass_action_id != undefined)
const iccidSet = new Set<string>(iccids)
console.log("iccidSet", iccidSet)
// 1. Una peticion por cada accion a comprobar // 1. Una peticion por cada accion a comprobar
// Las peticiones por iccid u otro filtro tardan ~50s // Las peticiones por iccid u otro filtro tardan ~50s
for (const originalAction of mass_actions) { for (const originalAction of mass_actions) {
@@ -79,18 +73,18 @@ export class CheckObjeniousRequests {
try { try {
res = await req res = await req
} catch (e) { } catch (e) {
console.error("Error comprobando el estado de ", originalAction) console.error("[cron] Error comprobando el estado de ", originalAction)
console.error("Error: ", e) console.error("[cron] Error: ", e)
return; return;
} }
const { data } = res const { data } = res
console.log("Estado de : ", originalAction.mass_action_id, originalAction.iccids) console.log("[cron] Estado de : ", originalAction.mass_action_id, originalAction.iccids)
console.log(res.status, data) console.log(res.status, data)
if (res.status != 200 || data == undefined) { if (res.status != 200 || data == undefined) {
console.error("Error buscando los massActions") console.error("[cron] Error buscando los massActions")
continue; continue;
} }
@@ -98,8 +92,7 @@ export class CheckObjeniousRequests {
const { id, status, info } = data const { id, status, info } = data
if (status != originalAction.objenious_status) { if (status != originalAction.objenious_status) {
console.log(status, "!=", originalAction.objenious_status) console.log("[cron] Actualizando", originalAction.id, originalAction.iccids, status)
console.log("Actualizando", originalAction, status)
const uorStatus = this.mapStatus(status) const uorStatus = this.mapStatus(status)
const updateData: ObjeniousOperationChange = { const updateData: ObjeniousOperationChange = {
operation_id: originalAction.id!, operation_id: originalAction.id!,
@@ -112,6 +105,27 @@ export class CheckObjeniousRequests {
originalAction.status = uorStatus; originalAction.status = uorStatus;
originalAction.objenious_status = status; originalAction.objenious_status = status;
originalAction.last_change_date = new Date().toISOString() originalAction.last_change_date = new Date().toISOString()
originalAction.end_date = originalAction.last_change_date
console.log(" ----> Status", uorStatus)
if (uorStatus /*== "finished"*/) {
console.log(" ****> Status", uorStatus)
const targetIccids = originalAction.iccids
const lineData = await this.getLineData(targetIccids)
console.log("lineData", lineData.content[0])
const msisdn = lineData.content[0].identifier.msisdn
this.notifyFinalization({
...originalAction,
msisdn
})
.then(e => {
console.log("Notificada la activacion de ", originalAction.iccids)
})
.catch(e => {
console.error("Error enviando la activacion de ", originalAction)
console.error(e)
})
}
if (info != undefined) { if (info != undefined) {
updateData.info = info updateData.info = info
@@ -144,6 +158,26 @@ export class CheckObjeniousRequests {
return res return res
} }
private async getLineData(iccids: string) {
const PATH = "/lines"
const req = this.httpClient.client.get(PATH, {
params: {
pageSize: 100, // no hace fata
"identifier.identifierType": "ICCID",
"identifier.identifiers": iccids
}
})
try {
const res = await req
return res.data
} catch (e) {
console.error("Error obteniendo datos de la sim")
throw new Error(String(e))
}
}
/** /**
* Refrescar los requests hasta que conseguir una Id de mass action * Refrescar los requests hasta que conseguir una Id de mass action
* Como no se puede consultar por * Como no se puede consultar por
@@ -191,10 +225,40 @@ export class CheckObjeniousRequests {
console.log("Error actualizando el estado de ", request) console.log("Error actualizando el estado de ", request)
continue; continue;
} }
} }
// 3. Se devuelve la lista de los requests con las actualizaciones // 3. Se devuelve la lista de los requests con las actualizaciones
return operationsList return operationsList
} }
/**
* Se devuelve la respuesta de una operacion completa de objenious
* al servicio que manda los mails
*/
private async notifyFinalization(operation: ObjeniousOperation & { msisdn: string }) {
console.log("Notificada, ", operation)
const req = axios.post(env.NOTIFICATION_URL, {
...operation,
iccids: [operation.iccids]
}, {
headers: {
"x-apikey-sim-activation": "9e48c4ac-1ab0-4397-b3f3-6c239200dfe6"
}
})
/*
const req = this.httpClient.client.post<any>("",
{ operation: operation },
{
headers: {
"x-apikey-sim-activation": "9e48c4ac-1ab0-4397-b3f3-6c239200dfe6"
},
baseURL: env.NOTIFICATION_URL
}
)*/
await req
}
} }

View File

@@ -13,11 +13,11 @@ export type ObjeniousOperation = {
operation: string; operation: string;
retry_count?: number; retry_count?: number;
max_retry?: number; max_retry?: number;
max_date_retry?: Date | null; max_date_retry?: string | null;
iccids: string[]; iccids: string; // Deberia ser string[] pero no parseo la lista de iccids
request_id?: string; request_id?: string;
mass_action_id?: string; mass_action_id?: string;
end_date?: Date | null; end_date?: string | null;
error?: string | null; error?: string | null;
status: StatusEnum; status: StatusEnum;
objenious_status?: string; objenious_status?: string;

View File

@@ -14,8 +14,7 @@ export class OperationsRepository implements IOperationsRepository {
INSERT INTO objenious_operation (operation, iccids, status, max_retry, request_id) INSERT INTO objenious_operation (operation, iccids, status, max_retry, request_id)
VALUES ($1, $2, $3, $4, $5) VALUES ($1, $2, $3, $4, $5)
RETURNING *`; RETURNING *`;
const iccids = JSON.stringify(data.iccids) const values = [data.operation, data.iccids, data.status, data.max_retry, data.request_id];
const values = [data.operation, iccids, data.status, data.max_retry, data.request_id];
const { rows } = await this.pgClient.query(query, values); const { rows } = await this.pgClient.query(query, values);
return <Result<string, ObjeniousOperation>>{ return <Result<string, ObjeniousOperation>>{
data: rows[0] data: rows[0]