xmlout.js 7.84 KB
var xmlrpc = require('xmlrpc');
var url = require('url');
var math = require('mathjs');
var winston = require('winston');

var logger;

var config;
var callbackReport;

var max_retry = 2;
var sleep_before_retry = 2000;

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

var aaa;

function topupRequest(task, retry) {
    if (config.globals.requests_count == undefined) {
        config.globals.requests_count = 1;
    } else {
        config.globals.requests_count++;
    }
    
    if (config.globals.active_requests_count == undefined) {
        config.globals.active_requests_count = 1;
    } else {
        config.globals.active_requests_count++;
    }
    
    if (config.globals.max_active_requests_count == undefined) {
        config.globals.max_active_requests_count = config.globals.active_requests_count;
    } else {
        config.globals.max_active_requests_count = math.max(config.globals.max_active_requests_count, config.globals.active_requests_count);
    }
    
    /*    
    if (retry === undefined) {
        retry = max_retry;
    }
    */

    var partnerUrl = url.parse(config.h2h_out.partner);
    var clientOptions = {
        host: partnerUrl.hostname
        , port: partnerUrl.port
        , path: partnerUrl.pathname
    };
    logger.info('Preparing XMLRPC client options', {options: clientOptions});

    var client;
    if (partnerUrl.protocol == 'https:') {
        client = xmlrpc.createSecureClient(clientOptions);
    } else {
        client = xmlrpc.createClient(clientOptions);
    }
    
    var params = {
        MSISDN: config.h2h_out.userid,
        REQUESTID: task['requestId'],
        PIN: config.h2h_out.password,
        NOHP: task['destination'],
        NOM: task['remoteProduct']
    };
    
    var methodName = 'topUpRequest';
    logger.info('Preparing XMLRPC client method', {methodname: methodName, params: params});

    client.methodCall(methodName, [ params ], function (error, value) {
        
        if (config.globals.active_requests_count == undefined) {
            config.globals.active_requests_count = 0;
        } else {
            config.globals.active_requests_count--;
        }
        
        // Results of the method response
        if (error) {
            
            logger.warn('XMLRPC Client Error', {requestId: task['requestId'], errorMessage: error});
            
            if (retry) {
                
                logger.info('Retrying topUpRequest (' + retry + ')');
                setTimeout(function() {
                    topupRequest(task, retry - 1);
                }, sleep_before_retry);
                
            } else {
                callbackReport(task['requestId'], '91', 'Gangguan koneksi ke suplier: ' + error);
            }
            return;
        }
        
        logger.info('Got XMLRPC response from partner for', {response_method: methodName, response_message: value});
        
        if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') {
            value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE'];
        }
        
        callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']);
    });
}

function createServer() {

    logger.info('Creating XML-RPC server on port ' + config.h2h_out.listen_port);
    var serverOptions = {
        port: config.h2h_out.listen_port
    };

    var server = xmlrpc.createServer(serverOptions);

    server.on('NotFound', function (method, params) {
        logger.warn('Unknown method recevied on XMLRPC server', {xmlrpc_method: method, xmlrpc_params: params});
    });

    server.on('topUpReport', function (err, params, callback) {
    
        logger.info('Got XMLRPC topUpReport request from partner', {xmlrpc_method: 'topUpReport', xmlrpc_params: params});
        
        var paramscount = params.length;
        for (var i = 0; i < paramscount; i++) {
            var value = params[i];
            
            if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') {
                value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE'];
            }
            callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']);
        }

        callback(null, 'ACK REPORT OK');
    })

}

function getBalanceFromMessage(message, balance_regex) {
    if (!balance_regex) {
        if (config && config.globals && config.globals.balance_regex) {
            balance_regex = config.globals.balance_regex;
        }
    }
    
    if (!balance_regex) {
        return;
    }
    
    try {
        var re = new RegExp(balance_regex);
        var matches = message.match(re);
        
        var result = matches[1];
        result = result.replace(/\./g, '');
        result = result.replace(/,/g, '');
        
        
        return Number(result);
    }
    catch(err) {
        return;
    }
}

function updateBalance(message) {
    var balance = getBalanceFromMessage(message);
    if (balance) {
        logger.info('Balance: ' + balance);
        aaa.updateBalance(balance);
    }
}

function checkStatus(task) {
    var partnerUrl = url.parse(config.h2h_out.partner);
    var clientOptions = {
        host: partnerUrl.hostname
        , port: partnerUrl.port
        , path: partnerUrl.pathname
    };
    logger.info('XMLRPC client options:');
    logger.info(clientOptions);

    var client;
    if (partnerUrl.protocol == 'https:') {
        client = xmlrpc.createSecureClient(clientOptions);
    } else {
        client = xmlrpc.createClient(clientOptions);
    }

    var methodName = 'topUpInquiry';
    logger.info('methodName: ' + methodName);

    var params = {
        MSISDN: config.h2h_out.userid,
        REQUESTID: task['requestId'],
        PIN: config.h2h_out.password,
        NOHP: task['destination']
    };
    logger.info('PARAMS:');
    logger.info(params);

    client.methodCall(methodName, [ params ], function (error, value) {
        // Results of the method response
        if (error) {
            logger.warn('Error: ');
            logger.warn(error);
            return;
        }
        logger.info('Method response for \'' + methodName, {response: value});

        callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']);
    });
}

function start(_config, _callbackReport, options) {
    config = _config;
    callbackReport = _callbackReport;
    
    if (options && options.aaa) {
            aaa = options.aaa;
    }
    
    if (options && options.logger) {
        logger = options.logger;
    } else {
        logger = new winston.Logger({
            transports: [
              new (winston.transports.Console)()
            ]
        });
    }

    createServer();
}

function parseSN(message, _config) {
    
    if (!_config) {
        _config = config;
    }
    
    var sn_regex = new RegExp(_config.h2h_out.sn_pattern);
    var sn_match = message.match(sn_regex);
        
    if (sn_match <= 0) {
        logger.info('SN Not found: ' + message);
        return '';
    }
    
    var match_index = 0;
    if (_config.h2h_out.sn_match_index) {
        match_index = Number(_config.h2h_out.sn_match_index)
    }
    
    var sn = sn_match[match_index];
    
    if (_config.h2h_out.sn_remove_whitespace) {
        sn = sn.replace(/\s/g, '');
    }
    
    var sn_remove_patterns = [];
    if (_config.h2h_out.sn_remove_patterns && _config.h2h_out.sn_remove_patterns_separator) {
        sn_remove_patterns = _config.h2h_out.sn_remove_patterns.split(_config.h2h_out.sn_remove_patterns_separator);
    }
    var count = sn_remove_patterns.length;
    
    for(var i = 0; i < count; i++) {
        
        //sn = sn.replace(sn_remove_patterns[i], '');
        
        var re = new RegExp(sn_remove_patterns[i], 'g');
        sn = sn.replace(re, '');
    }
    
    //sn = paddingSN(sn, _config);
    
    return sn.trim();
}

exports.start = start;
exports.topupRequest = topupRequest;
exports.getBalanceFromMessage = getBalanceFromMessage;