index.js 3.36 KB
const MODULE_NAME = 'POSTPAID-SDK';

const config = require('komodo-sdk/config');

const DEFAULT_CORE_REQUEST_TIMEOUT = 15 * 1000;
const DEFAULT_SLEEP_AFTER_CORE_ERROR_MS = 3000;
const PULL_INTERVAL_MS = config.postpaid_pull_interval_ms || config.pull_interval_ms || 1000;

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 axios = require('axios').default;
const uniqid = require('uniqid');
const coreUrl = require('komodo-sdk/core-url');
const logger = require('tektrans-logger');
const report = require('./lib/report');

const sleep = require('./lib/sleep');
const composeGatewayLocations = require('./lib/compose-gateway-locations');

let partner;
let first = true;
let coreIsHealthy = null;

const CORE_ENDPOINT = `${coreUrl}/postpaid2/task`;

function detectCoreStatusChange(isHealthy, url, err) {
    if (coreIsHealthy !== isHealthy) {
        coreIsHealthy = isHealthy;

        if (isHealthy) {
            logger.info(`${MODULE_NAME} D7F6DBE4: CORE is healthy now`, {
                url, err: err && err.message,
            });
        } else {
            logger.warn(`${MODULE_NAME} 460EC596: CORE is unhealthy now`, {
                url, err: err && err.message,
            });
        }
    }
}

async function getTask() {
    if (!partner) return null;

    const xid = uniqid();

    if (first) {
        first = false;
        logger.verbose(`${MODULE_NAME} 20A30442: First getTask pull request to CORE`, { xid });
    }

    const payload = {
        handler: config.handler || config.handler_name,
        products: config.products || [],
        locations: composeGatewayLocations(config),
    };

    let task;
    try {
        const result = await axios.post(
            CORE_ENDPOINT,
            payload,
            GET_TASK_AXIOS_CONFIG,
        );

        if (!result || !result.data) {
            throw new Error(`${MODULE_NAME} 26F332C6: Empty CORE response on pulling task`);
        }

        if (result && result.data && result.data.task && !result.data.task.postpaid) {
            throw new Error(`${MODULE_NAME} B338CEF8: CORE returning non postpaid task on pulling task`);
        }

        detectCoreStatusChange(true, CORE_ENDPOINT);
        task = result.data.task;
    } catch (e) {
        // skipNext = 3;
        detectCoreStatusChange(false, CORE_ENDPOINT, 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(`${MODULE_NAME} 441E8C96: Got task from CORE on pulling task`, { xid, task });

    if (task.inquiry_only) {
        if (typeof partner.inquiry === 'function') partner.inquiry(task, xid);
        return task;
    }

    if (typeof partner.pay === 'function') {
        partner.pay(task, xid);
        return task;
    }

    return null;
}

const getTaskLooper = async () => {
    await getTask();

    setTimeout(() => {
        getTaskLooper();
    }, PULL_INTERVAL_MS);
};

exports.setPartner = (val) => {
    partner = val;
    // setInterval(getTaskLooper, config.pull_interval_ms || 1000);
    getTaskLooper();
};

exports.report = report;