diff --git a/k8s/airflow/values-prod.yaml b/k8s/airflow/values-prod.yaml index 17c8706f9a..3b00330c9e 100644 --- a/k8s/airflow/values-prod.yaml +++ b/k8s/airflow/values-prod.yaml @@ -9,7 +9,7 @@ images: repositories: initContainer: eu.gcr.io/airqo-250220/airqo-apache-airflow-xcom containers: eu.gcr.io/airqo-250220/airqo-apache-airflow - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' podAnnotations: {} diff --git a/k8s/analytics/values-prod.yaml b/k8s/analytics/values-prod.yaml index 581bb12197..a452900b58 100644 --- a/k8s/analytics/values-prod.yaml +++ b/k8s/analytics/values-prod.yaml @@ -8,7 +8,7 @@ images: celeryWorker: eu.gcr.io/airqo-250220/airqo-analytics-celery-worker reportJob: eu.gcr.io/airqo-250220/airqo-analytics-report-job devicesSummaryJob: eu.gcr.io/airqo-250220/airqo-analytics-devices-summary-job - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 api: name: airqo-analytics-api label: analytics-api diff --git a/k8s/auth-service/values-prod.yaml b/k8s/auth-service/values-prod.yaml index 69ae2be72f..389bc7540f 100644 --- a/k8s/auth-service/values-prod.yaml +++ b/k8s/auth-service/values-prod.yaml @@ -6,7 +6,7 @@ app: replicaCount: 3 image: repository: eu.gcr.io/airqo-250220/airqo-auth-api - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' podAnnotations: {} diff --git a/k8s/device-monitor/values-prod.yaml b/k8s/device-monitor/values-prod.yaml index 5fc943f853..213d0ba538 100644 --- a/k8s/device-monitor/values-prod.yaml +++ b/k8s/device-monitor/values-prod.yaml @@ -9,7 +9,7 @@ images: deviceMonitor: eu.gcr.io/airqo-250220/airqo-device-monitor-api celeryBeat: eu.gcr.io/airqo-250220/airqo-device-monitor-celery-beat celeryWorker: eu.gcr.io/airqo-250220/airqo-device-monitor-celery-worker - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' podAnnotations: {} diff --git a/k8s/device-registry/values-prod.yaml b/k8s/device-registry/values-prod.yaml index f18b0d5360..672e03af2c 100644 --- a/k8s/device-registry/values-prod.yaml +++ b/k8s/device-registry/values-prod.yaml @@ -6,7 +6,7 @@ app: replicaCount: 3 image: repository: eu.gcr.io/airqo-250220/airqo-device-registry-api - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' podAnnotations: {} diff --git a/k8s/device-registry/values-stage.yaml b/k8s/device-registry/values-stage.yaml index 151e6bdf55..993255a92b 100644 --- a/k8s/device-registry/values-stage.yaml +++ b/k8s/device-registry/values-stage.yaml @@ -6,7 +6,7 @@ app: replicaCount: 2 image: repository: eu.gcr.io/airqo-250220/airqo-stage-device-registry-api - tag: stage-c32fcdc5-1699219582 + tag: stage-86bad23b-1699224239 nameOverride: '' fullnameOverride: '' podAnnotations: {} diff --git a/k8s/exceedance/values-prod-airqo.yaml b/k8s/exceedance/values-prod-airqo.yaml index 9f49a6c1a4..adf4f99409 100644 --- a/k8s/exceedance/values-prod-airqo.yaml +++ b/k8s/exceedance/values-prod-airqo.yaml @@ -4,6 +4,6 @@ app: configmap: env-exceedance-production image: repository: eu.gcr.io/airqo-250220/airqo-exceedance-job - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' diff --git a/k8s/exceedance/values-prod-kcca.yaml b/k8s/exceedance/values-prod-kcca.yaml index 3799021abe..f00814c371 100644 --- a/k8s/exceedance/values-prod-kcca.yaml +++ b/k8s/exceedance/values-prod-kcca.yaml @@ -4,6 +4,6 @@ app: configmap: env-exceedance-production image: repository: eu.gcr.io/airqo-250220/kcca-exceedance-job - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' diff --git a/k8s/gp-model/values-prod.yaml b/k8s/gp-model/values-prod.yaml index 4ad5f044a4..3e0d406bcf 100644 --- a/k8s/gp-model/values-prod.yaml +++ b/k8s/gp-model/values-prod.yaml @@ -6,7 +6,7 @@ app: namespace: production configMap: env-gp-model-production images: - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 repositories: cronJob: eu.gcr.io/airqo-250220/airqo-gp-model-job brokerConsumer: eu.gcr.io/airqo-250220/airqo-gp-model-broker-consumer diff --git a/k8s/incentives/values-prod.yaml b/k8s/incentives/values-prod.yaml index f38ce3629d..f26e3787f4 100644 --- a/k8s/incentives/values-prod.yaml +++ b/k8s/incentives/values-prod.yaml @@ -6,7 +6,7 @@ app: replicaCount: 3 image: repository: eu.gcr.io/airqo-250220/airqo-incentives-api - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 nameOverride: '' fullnameOverride: '' podAnnotations: {} diff --git a/k8s/predict/values-prod.yaml b/k8s/predict/values-prod.yaml index 3183599939..3e3173ae8d 100644 --- a/k8s/predict/values-prod.yaml +++ b/k8s/predict/values-prod.yaml @@ -7,7 +7,7 @@ images: predictJob: eu.gcr.io/airqo-250220/airqo-predict-job trainJob: eu.gcr.io/airqo-250220/airqo-train-job predictPlaces: eu.gcr.io/airqo-250220/airqo-predict-places-air-quality - tag: prod-6ea06af8-1699219770 + tag: prod-58e0f4e4-1699224315 api: name: airqo-prediction-api label: prediction-api diff --git a/src/incentives/bin/cronJob.js b/src/incentives/bin/cronJob.js new file mode 100644 index 0000000000..5e54881746 --- /dev/null +++ b/src/incentives/bin/cronJob.js @@ -0,0 +1,58 @@ +const cron = require("node-cron"); +const SimModel = require("@models/Sim"); +const constants = require("@config/constants"); +const log4js = require("log4js"); +const logger = log4js.getLogger( + `${constants.ENVIRONMENT} -- bin/cronJob script` +); +const checkStatus = require("@utils/create-sim").checkStatus; +const secondsDelayBetweenRequests = 20000; +const internetDataBalanceThreshold = 5; + +// Everyday at midnight +cron.schedule("0 0 * * *", async () => { + try { + const batchSize = 100; // Process 100 SIM cards at a time + let skip = 0; + + const simCards = await SimModel("airqo").find({}).select("_id").lean(); + + while (true) { + const simBatch = simCards.slice(skip, skip + batchSize); + + if (simBatch.length === 0) { + break; + } + + await processSimCardsWithDelay(simBatch); + + skip += batchSize; + } + } catch (error) { + logger.error( + `An error occurred in the cron job --- ${JSON.stringify(error)}` + ); + } +}); + +async function processSimCardsWithDelay(simBatch) { + for (const sim of simBatch) { + const responseFromCheckStatus = await checkStatus({ + query: { tenant: "airqo" }, + params: { sim_id: sim._id }, + }); + + // Check if data.balance is less than the declared threshold and log it + if ( + responseFromCheckStatus.success && + responseFromCheckStatus.data.balance < internetDataBalanceThreshold + ) { + logger.info( + `SIM card ${sim._id} has a balance less than ${internetDataBalanceThreshold}` + ); + } + await new Promise((resolve) => + setTimeout(resolve, secondsDelayBetweenRequests) + ); + } +} diff --git a/src/incentives/package-lock.json b/src/incentives/package-lock.json index 53276b6267..1a05daf3f7 100644 --- a/src/incentives/package-lock.json +++ b/src/incentives/package-lock.json @@ -35,6 +35,7 @@ "mongoose-unique-validator": "^2.0.3", "morgan": "~1.9.0", "mtn-momo": "^2.0.0", + "node-cron": "^3.0.2", "node-fetch": "^2.6.1", "node-schedule": "^2.1.1", "nodemailer": "^6.9.4", @@ -5868,6 +5869,25 @@ "node": ">=4.0.0" } }, + "node_modules/node-cron": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", + "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/node-cron/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -13209,6 +13229,21 @@ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, + "node-cron": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.2.tgz", + "integrity": "sha512-iP8l0yGlNpE0e6q1o185yOApANRe47UPbLf4YxfbiNHt/RU5eBcGB/e0oudruheSf+LQeDMezqC5BVAb5wwRcQ==", + "requires": { + "uuid": "8.3.2" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, "node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", diff --git a/src/incentives/package.json b/src/incentives/package.json index d1b87fcd22..4a09aad1e8 100644 --- a/src/incentives/package.json +++ b/src/incentives/package.json @@ -54,6 +54,7 @@ "mongoose-unique-validator": "^2.0.3", "morgan": "~1.9.0", "mtn-momo": "^2.0.0", + "node-cron": "^3.0.2", "node-fetch": "^2.6.1", "node-schedule": "^2.1.1", "nodemailer": "^6.9.4",