diff --git a/index.js b/index.js new file mode 100644 index 0000000..5db1bc1 --- /dev/null +++ b/index.js @@ -0,0 +1,171 @@ +const DEFAULT_CORE_REQUEST_TIMEOUT = 5 * 1000; +const MAX_REPORT_RETRY = 30; +const REPORT_RETRY_SLEEP_MS = 2000; + +const axios = require('axios').default; + +const config = require('komodo-sdk/config'); +const coreUrl = require('komodo-sdk/core-url'); +const logger = require('komodo-sdk/logger'); + +let partner; +let first = true; +let coreIsHealthy = null; +let skipNext = 0; + +const DEFAULT_CORE_AXIOS_CONFIG = { + headers: { 'Content-Type': 'application/json' }, + timeout: config.core_request_timeout || config.request_timeout || DEFAULT_CORE_REQUEST_TIMEOUT, +}; + +const GET_TASK_AXIOS_CONFIG = DEFAULT_CORE_AXIOS_CONFIG; +const REPORT_AXIOS_CONFIG = DEFAULT_CORE_AXIOS_CONFIG; + +function detectCoreStatusChange(isHealthy, url, err) { + if (coreIsHealthy !== isHealthy) { + coreIsHealthy = isHealthy; + + if (isHealthy) { + logger.info('POSTPAID2-SDK: CORE is healthy now', { url, err: err && err.message }); + } else { + logger.warn('POSTPAID2-SDK: CORE is unhealthy now', { url, err: err && err.message }); + } + } +} + +async function getTask() { + if (!partner) return; + + if (skipNext > 0) { + skipNext -= 1; + return; + } + + if (first) { + first = false; + logger.verbose('POSTPAID2-SDK: first pull request to CORE'); + } + + const coreEndpoint = `${coreUrl}/postpaid2/task`; + + const payload = { + handler: config.handler || config.handler_name, + products: config.products || [], + }; + + let task; + try { + const result = await axios.post( + coreEndpoint, payload, GET_TASK_AXIOS_CONFIG, + ); + + if (!result || !result.data) throw new Error('POSTPAID2-SDK: Empty CORE response on pulling task. MARK-26F332C6'); + if (result && result.data && result.data.task && !result.data.task.postpaid) throw new Error('POSTPAID2-SDK: CORE returning non postpaid task on pulling task. MARK-B338CEF8'); + + detectCoreStatusChange(true, coreEndpoint); + task = result.data.task; + } catch (e) { + skipNext = 3; + detectCoreStatusChange(false, coreEndpoint, e); + } + + if (!task) return; + + task.remote_product = ((config.remote_products || {})[task.product]) || task.product; + + logger.verbose('POSTPAID2-SDK: Got task from CORE on pulling task', { task }); + + if (task.inquiry_only) { + if (typeof partner.inquiry === 'function') partner.inquiry(task); + return; + } + + if (typeof partner.pay === 'function') partner.pay(task); +} + +const getTaskLooper = async () => { + await getTask(); + + setTimeout(() => { + getTaskLooper(); + }, config.pull_interval_ms || 1000); +}; + +exports.setPartner = (val) => { + partner = val; + setInterval(getTaskLooper, config.pull_interval_ms || 1000); +}; + +exports.report = async (data, xid, retry) => { + if (!data.trx_id) { + logger.warn('POSTPAID2-SDK: INVALID DATA TO REPORT. No trx id in report. MARK-3A37B7CA', { xid, data }); + return; + } + + if (!data.rc || typeof data.rc !== 'string') { + logger.warn('POSTPAID2-SDK: INVALID DATA TO REPORT. Rc is not valid. MARK-41ED74FC', { + xid, trxId: data.trx_id, rc: data.rc, typeofRc: typeof data.rc, + }); + } + + const dataToReport = { + handler: config.handler || config.handler_name, + command: data.command, + trx_id: data.trx_id, + rc: data.rc, + sn: data.sn, + amount: data.amount, + base_bill_amount: data.base_bill_amount, + bill_count: data.bill_count, + message: data.message, + info: data.info, + detail: data.detail, + data: data.data, + }; + + logger.verbose('POSTPAID2-SDK: Going to report to CORE', { + xid, + trxId: data.trx_id, + rc: data.rc, + sn: data.sn, + amount: data.amount, + baseBillAmount: data.base_bill_amount, + }); + + const coreEndpoint = `${coreUrl}/postpaid2/report`; + + try { + const reportResult = await axios.post( + coreEndpoint, JSON.stringify(dataToReport), REPORT_AXIOS_CONFIG, + ); + + if (!reportResult) { + logger.warn('POSTPAID2-SDK: unknown result from CORE on reporting trx result. MARK-795C53DB'); + } + } catch (e) { + const newRetry = (retry || 0) + 1; + logger.warn('POSTPAID2-SDK: Exception on reporting trx result to CORE. MARK-E7F000D8', { + xid, err: e.message, retry: newRetry, maxRetry: MAX_REPORT_RETRY, + }); + + if (!this || !this.report) { + logger.warn('POSTPAID2-SDK: Can not retry report because of unkown this.report!'); + return; + } + + if (newRetry < MAX_REPORT_RETRY) { + setTimeout(() => { + logger.info('POSTPAID2-SDK: Retrying to send report to CORE', { + xid, + trxId: data.trx_id, + rc: data.rc, + sn: data.sn, + amount: data.amount, + baseBillAmount: data.base_bill_amount, + }); + + this.report(data, xid, newRetry); + }, REPORT_RETRY_SLEEP_MS); + } + } +};