Commit 4c6bd69790eccd1714826babe302b5f45f0a0731

Authored by Adhidarma Hadiwinoto
1 parent 816ab0c381
Exists in master

topupStatus

Showing 2 changed files with 176 additions and 10 deletions Side-by-side Diff

... ... @@ -21,6 +21,7 @@
21 21 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>",
22 22 "license": "ISC",
23 23 "dependencies": {
  24 + "redis": "^2.6.2",
24 25 "request": "^2.74.0",
25 26 "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git",
26 27 "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git",
1 1 var xml2js = require('xml2js');
2 2 var request = require('request');
3 3 var http = require('http');
  4 +var redis = require('redis');
  5 +var resendDelay = require('sate24/resend-delay.js')
4 6  
5 7 var aaa;
6 8 var _callbackReport;
7 9 var config;
8 10 var logger;
  11 +var redisClient;
9 12  
10 13 var xmlBuilder = new xml2js.Builder();
11 14  
... ... @@ -37,21 +40,34 @@ function start(options) {
37 40 process.exit(1);
38 41 }
39 42  
  43 + createRedisClient(config.globals.redis_host, config.globals.redis_port);
40 44 createServer();
41 45  
42   - /*
43 46 resendDelay.init({
44 47 config: config,
45   - topupRequest: topupRequest,
  48 + topupRequest: topupStatus,
46 49 logger: logger
47 50 });
48   - */
49 51 }
50 52  
51 53 function topupRequest(task) {
52 54 aaa.insertTaskToMongoDb(task);
53 55  
54   - var payload = composeTopupStatusMessage(
  56 + getTaskFromHistory(task, function(err, archivedTask) {
  57 + putTaskToHistory(task);
  58 +
  59 + if (archivedTask) {
  60 + logger.info('Task has been executed before, going to checkStatus', {task: task, archivedTask: archivedTask});
  61 + topupStatus(task);
  62 + } else {
  63 + _topupRequest(task);
  64 + }
  65 + });
  66 +}
  67 +
  68 +function _topupRequest(task) {
  69 +
  70 + var payload = composeTopupMessage(
55 71 config.h2h_out.pin,
56 72 task.remoteProduct,
57 73 task.destination,
... ... @@ -64,20 +80,48 @@ function topupRequest(task) {
64 80 body: payload,
65 81 headers: {
66 82 'Content-Type': 'text/xml',
67   - //'Content-Length': Buffer.byteLength(payload)
68 83 }
69 84 };
70 85  
71   - logger.verbose('Requesting to partner', {reqOpts: reqOpts, payload: payload});
  86 + logger.verbose('Requesting TOPUP to partner', {reqOpts: reqOpts, payload: payload});
  87 + request(reqOpts, function (err, response, body) {
  88 + if (err) {
  89 + var msg = 'Error requesting TOPUP to partner: ' + err;
  90 + logger.warn(msg, {task: task, err: err});
  91 + callbackReport(task.requestId, '68', msg);
  92 + return;
  93 + }
  94 +
  95 + logger.verbose('Got a direct response from TOPUP', {response: body, task: task});
  96 + topupResponseHandler(body, task.requestId, callbackReport);
  97 + });
  98 +}
  99 +
  100 +function topupStatus(task) {
  101 + var payload = composeTopupStatusMessage(
  102 + config.h2h_out.pin,
  103 + task.requestId
  104 + );
  105 +
  106 + var reqOpts = {
  107 + url: config.h2h_out.partner,
  108 + method: "POST",
  109 + body: payload,
  110 + headers: {
  111 + 'Content-Type': 'text/xml',
  112 + }
  113 + };
  114 +
  115 + logger.verbose('Requesting TOPUPSTATUS to partner', {reqOpts: reqOpts, payload: payload});
72 116 request(reqOpts, function (err, response, body) {
73 117 if (err) {
74   - var msg = 'Error requesting to partner: ' + err;
  118 + var msg = 'Error requesting TOPUPSTATUS to partner: ' + err;
75 119 logger.warn(msg, {task: task, err: err});
76 120 callbackReport(task.requestId, '68', msg);
77 121 return;
78 122 }
79 123  
80   - logger.verbose('Got a direct response from partner', {response: body, task: task});
  124 + logger.verbose('Got a direct response from TOPUPSTATUS', {response: body, task: task});
81 125 topupResponseHandler(body, task.requestId, callbackReport);
82 126 });
83 127 }
... ... @@ -162,7 +206,7 @@ function modifyMessageWithSn(msg) {
162 206 return msg;
163 207 }
164 208  
165   -function composeTopupStatusMessage(pin, product, destination, requestId) {
  209 +function composeTopupMessage(pin, product, destination, requestId) {
166 210 var data = {fm: {
167 211 command: 'TOPUP',
168 212 pin: pin,
... ... @@ -174,6 +218,16 @@ function composeTopupStatusMessage(pin, product, destination, requestId) {
174 218 return xmlBuilder.buildObject(data);
175 219 }
176 220  
  221 +function composeTopupStatusMessage(pin, requestId) {
  222 + var data = {fm: {
  223 + command: 'TOPUPSTATUS',
  224 + pin: pin,
  225 + refTrxid: requestId
  226 + }}
  227 +
  228 + return xmlBuilder.buildObject(data);
  229 +}
  230 +
177 231 function createServer() {
178 232 var httpServer = http.createServer(function(request, response) {
179 233  
... ... @@ -199,8 +253,119 @@ function createServer() {
199 253 });
200 254 }
201 255  
  256 +function createRedisClient(host, port) {
  257 + if (!host && !port) {
  258 + logger.info('Not creating redis client because unspecified host or port');
  259 + return;
  260 + }
  261 +
  262 + try {
  263 + redisClient = redis.createClient(port, host);
  264 + } catch(err) {
  265 + logger.warn("Error creating redis client to " + host + ':' + port);
  266 + }
  267 +}
  268 +
  269 +function getTaskKey(task, chipInfo) {
  270 + var requestId;
  271 +
  272 + if (typeof task === 'string') {
  273 + requestId = task;
  274 + } else {
  275 + try {
  276 + requestId = task.requestId;
  277 + }
  278 + catch(e) {
  279 + logger.warn('Something wrong', {task: task});
  280 + console.trace('Cekidot');
  281 + process.exit(1);
  282 + }
  283 +
  284 + }
  285 +
  286 + if (!chipInfo && config && config.globals && config.globals.gateway_name) {
  287 + chipInfo = config.globals.gateway_name;
  288 + }
  289 +
  290 + return chipInfo + '.hitachi.rid:' + requestId;
  291 +}
  292 +
  293 +
  294 +function putTaskToHistory(task, cb) {
  295 + if (Number(config.globals.no_dupe_check)) {
  296 + if (cb) { cb(); }
  297 + return;
  298 + }
  299 + var key = getTaskKey(task, config.globals.gateway_name);
  300 + logger.verbose('Saving task to history LRU', {key: key, task: task});
  301 +
  302 + try {
  303 + taskHistory.set(key, JSON.parse(JSON.stringify(task)));
  304 + } catch (e) { }
  305 +
  306 + putTaskToRedis(task, cb);
  307 +}
  308 +
  309 +function putTaskToRedis(task, cb) {
  310 + if (!redisClient) {
  311 + logger.verbose('Not saving to redis because of undefined redisClient')
  312 + if (cb) { cb(); }
  313 + return;
  314 + }
  315 +
  316 + var key = getTaskKey(task, config.globals.gateway_name);
  317 + logger.verbose('Saving task to redis', {key: key, task: task});
  318 +
  319 + redisClient.set(key, JSON.stringify(task), function() {
  320 + redisClient.expire(key, 3600*24*30);
  321 + if (cb) {
  322 + cb();
  323 + }
  324 + });
  325 +}
  326 +
  327 +function getTaskFromHistory(task, cb) {
  328 + logger.verbose('Getting task from history', {task: task});
  329 + var key = getTaskKey(task, config.globals.gateway_name);
  330 + var archive = taskHistory.get(key);
  331 +
  332 + if (archive) {
  333 + if (cb) { cb(null, archive); }
  334 + }
  335 + else {
  336 + getTaskFromRedis(task, cb);
  337 + }
  338 +}
  339 +
  340 +function getTaskFromRedis(task, cb) {
  341 + if (!redisClient) {
  342 + if (cb) { cb(null, null); }
  343 + return;
  344 + }
  345 +
  346 + var key = getTaskKey(task, config.globals.gateway_name);
  347 + redisClient.get(key, function(err, result) {
  348 + if (err) {
  349 + logger.warn('Error retrieving task from redis', {err: err});
  350 + cb(err, null);
  351 + return;
  352 + }
  353 +
  354 + var task;
  355 + try {
  356 + task = JSON.parse(result);
  357 + }
  358 + catch(e) {
  359 + logger.warn('Exception on parsing redis result as a json', {err: e});
  360 + }
  361 +
  362 + cb(null, task);
  363 + })
  364 +}
  365 +
  366 +
202 367 exports.start = start;
203 368 exports.topupRequest = topupRequest;
204   -exports.composeTopupStatusMessage = composeTopupStatusMessage;
  369 +exports.composeTopupMessage = composeTopupMessage;
205 370 exports.getSnFromMessage = getSnFromMessage;
206 371 exports.modifyMessageWithSn = modifyMessageWithSn;