var winston = require('winston'); var request = require('request'); var xmlrpc = require('xmlrpc'); var url = require('url'); var http = require('http'); var mongoClient = require('mongodb').MongoClient; var strftime = require('strftime'); var moment = require('moment'); var max_retry = 6; var sleep_before_retry = 10000; process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; var config; var callbackReport; var aaa; var logger; var options; var mongodb; 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)() ] }); } createXMLRPCServer(); initMongoClient(); } function createXMLRPCServer() { 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]; var responseTs = strftime('%Y-%m-%d %H:%M:%S', new Date()); var dummyTask = { requestId: value.REQUESTID }; if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') { value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE']; } if (value['RESPONSECODE'] != '00' && value['RESPONSECODE'] != '68') { value['RESPONSECODE'] = getResponseCodeByMessage(value['MESSAGE']); } pushResponseToMongoDb(dummyTask, {ts: responseTs, supplier: config.globals.gateway_name, raw: JSON.stringify(value), parsed: value}, value['RESPONSECODE']); callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']); } callback(null, 'ACK REPORT OK'); }) } function getResponseCodeByMessage(msg) { if (msg.indexOf("Trx XL-AXIS NO SALAH") >= 0) { return '14'; } else if (msg.indexOf("gagal Nomer salah/Nomer Belum Aktif") >= 0) { return '14'; } else if (msg.indexOf("GAGAL NOMER SALAH") >= 0) { return '14'; } else if (msg.indexOf("GAGAL NOMER SALAH") >= 0) { return '14'; } else { return '40' } } function topupRequestHttpGet(task, retry) { var options = { method: 'GET', url: config.h2h_out.partner, qs: { id: config.h2h_out.userid, pin: config.h2h_out.pin, user: config.h2h_out.user, pass: config.h2h_put.password, kodeproduk: task.remoteProduct, tujuan: task.destination, idtrx: task.requestId } } request(options, function(err, res, body) { }); } function topupRequestXMLRPC(task, 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) { // Results of the method response if (error) { logger.warn('XMLRPC Client Error', {requestId: task['requestId'], errorMessage: error}); var responseTs = strftime('%Y-%m-%d %H:%M:%S', new Date()); var dummyValue = { MESSAGE: 'GENERATED: XMLRPC Client Error. ' + error, RESPONSECODE: '68', REQUESTID: task.requestId, } try { dummyValue.HTTP_STATUS = error.res && error.res.statusCode; dummyValue.RESPONSEBODY = error.body; } catch(errRB) {} if (retry) { dummyValue.MESSAGE = dummyValue.MESSAGE + '. Retrying (' + retry + ')'; logger.info(dummyValue.MESSAGE); setTimeout(function() { topupRequest(task, retry - 1); }, sleep_before_retry); } else { callbackReport(task['requestId'], '68', 'GENERATED: Silahkan resend. Gangguan koneksi ke suplier: ' + error); } pushResponseToMongoDb( task, { ts: responseTs, supplier: config.globals.gateway_name, raw: JSON.stringify(dummyValue), parsed: dummyValue }, '68' ); return; } logger.info('Got XMLRPC response from partner for', {response_method: methodName, response_message: value}); var responseTs = strftime('%Y-%m-%d %H:%M:%S', new Date()); /* if (value['RESPONSECODE'] == '00' && config.h2h_out.parse_sn == 'YES') { value['MESSAGE'] = 'SN=' + parseSN(value['MESSAGE']) + '; ' + value['MESSAGE']; } */ if (value['RESPONSECODE'] != '00' && value['RESPONSECODE'] != '68') { value['RESPONSECODE'] = getResponseCodeByMessage(value['MESSAGE']); } /* if (value['RESPONSECODE'] != '00') { try { value['MESSAGE'] = value['MESSAGE'].replace(/\.;/, ';'); } catch(errReplaceDot) { } } */ pushResponseToMongoDb(task, {ts: responseTs, supplier: config.globals.gateway_name, raw: JSON.stringify(value), parsed: value}, value['RESPONSECODE']); callbackReport(value['REQUESTID'], value['RESPONSECODE'], value['MESSAGE']); }); } function topupRequest(task, retry) { if (retry === undefined) { task.ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss'); task.ts_date = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD'); retry = max_retry; insertTaskToMongoDb(task); } topupRequestXMLRPC(task, retry); } function initMongoClient() { if (!config.mongodb || !config.mongodb.url) { return; } try { var url = config.mongodb.url; mongoClient.connect(url, function(err, db) { if (err) { logger.warn('Failed to connect to mongodb', {err: err}); return; } mongodb = db; logger.info('MongoDB connected'); }); } catch(err) { logger.warn('Exception when connecting to mongodb', {err: err, url: url}); } } function isMongoReady() { if (!config.mongodb) { return; } if (!config.mongodb.collection) { return; } if (!mongodb) { return; } return true; } function insertTaskToMongoDb(task) { if (!isMongoReady()) { return; } task.supplier = config.globals.gateway_name; task.rc = '68'; try { mongodb.collection(config.mongodb.collection).insertOne(task); } catch(err) { //logger.warn('Exception when inserting document to mongodb', {err: err, task: task}); } } function pushResponseToMongoDb(task, response, rc) { if (!isMongoReady()) { return; } try { mongodb.collection(config.mongodb.collection).updateOne( {requestId: task.requestId}, { $set: { lastResponse: response, supplier: config.globals.gateway_name, rc: rc }, $push: { responses: response } }, function(err, result) { if (err) { logger.warn('Error when pushing response to mongodb', {err: err, task: task, response: response}); return; } } ); } catch(err) { logger.warn('Exception when pushing response to mongodb', {err: err, task: task, response: response}); } } exports.start = start; exports.topupRequest = topupRequest;