const DEFAULT_CORE_REQUEST_TIMEOUT = 15 * 1000;
const DEFAULT_SLEEP_AFTER_CORE_ERROR_MS = 3000;
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('tektrans-logger');
const sleep = require('./lib/sleep');
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 null;
// if (skipNext > 0) {
// skipNext -= 1;
// return null;
// }
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);
await sleep(DEFAULT_SLEEP_AFTER_CORE_ERROR_MS);
}
if (!task) return null;
task.remote_product = ((config.remote_products || {})[task.product]) || task.product;
task.trx_id = Number(task.trx_id) + (config.sdk_trx_id_adder || 0);
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 task;
}
if (typeof partner.pay === 'function') {
partner.pay(task);
return task;
}
return null;
}
const getTaskLooper = async () => {
await getTask();
setTimeout(() => {
getTaskLooper();
}, config.postpaid_pull_interval_ms || config.pull_interval_ms || 1000);
};
exports.setPartner = (val) => {
partner = val;
// setInterval(getTaskLooper, config.pull_interval_ms || 1000);
getTaskLooper();
};
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: Number(data.trx_id) - (config.sdk_trx_id_adder || 0),
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,
struk: (typeof data.struk === 'string' && data.struk)
|| (data.struk && JSON.stringify(data.struk))
|| null,
};
const coreEndpoint = `${coreUrl}/postpaid2/report`;
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,
coreEndpoint,
});
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);
}
}
};