Commit 17c096e5cd7be3e5b0d3832bce22bb1533e4829c

Authored by Adhidarma Hadiwinoto
1 parent db380d6467
Exists in master

remove payload from double logging

Showing 1 changed file with 2 additions and 2 deletions Inline Diff

1 var xml2js = require('xml2js'); 1 var xml2js = require('xml2js');
2 var request = require('request'); 2 var request = require('request');
3 var http = require('http'); 3 var http = require('http');
4 var redis = require('redis'); 4 var redis = require('redis');
5 var resendDelay = require('sate24/resend-delay.js'); 5 var resendDelay = require('sate24/resend-delay.js');
6 var LRU = require('lru-cache'); 6 var LRU = require('lru-cache');
7 7
8 var aaa; 8 var aaa;
9 var _callbackReport; 9 var _callbackReport;
10 var config; 10 var config;
11 var logger; 11 var logger;
12 var redisClient; 12 var redisClient;
13 13
14 var xmlBuilder = new xml2js.Builder(); 14 var xmlBuilder = new xml2js.Builder();
15 var taskHistory = LRU({max: 500, maxAge: 1000 * 3600 * 2}); 15 var taskHistory = LRU({max: 500, maxAge: 1000 * 3600 * 2});
16 var alreadyPending = LRU({max: 500, maxAge: 1000 * 3600 * 2}); 16 var alreadyPending = LRU({max: 500, maxAge: 1000 * 3600 * 2});
17 17
18 function start(options) { 18 function start(options) {
19 if (!options) { 19 if (!options) {
20 console.log('Undefined options, terminating....'); 20 console.log('Undefined options, terminating....');
21 process.exit(1); 21 process.exit(1);
22 } 22 }
23 23
24 if (options.config) { 24 if (options.config) {
25 config = options.config; 25 config = options.config;
26 } else { 26 } else {
27 console.log('Undefined options.config, terminating....') 27 console.log('Undefined options.config, terminating....')
28 process.exit(1); 28 process.exit(1);
29 } 29 }
30 30
31 if (options.aaa) { 31 if (options.aaa) {
32 aaa = options.aaa; 32 aaa = options.aaa;
33 _callbackReport = options.aaa.callbackReportWithPushToMongoDb; 33 _callbackReport = options.aaa.callbackReportWithPushToMongoDb;
34 } else { 34 } else {
35 console.log('Undefined options.aaa, terminating....') 35 console.log('Undefined options.aaa, terminating....')
36 process.exit(1); 36 process.exit(1);
37 } 37 }
38 38
39 if (options && options.logger) { 39 if (options && options.logger) {
40 logger = options.logger; 40 logger = options.logger;
41 } else { 41 } else {
42 console.log('Undefined options.logger, terminating....') 42 console.log('Undefined options.logger, terminating....')
43 process.exit(1); 43 process.exit(1);
44 } 44 }
45 45
46 createRedisClient(config.globals.redis_host, config.globals.redis_port); 46 createRedisClient(config.globals.redis_host, config.globals.redis_port);
47 createServer(); 47 createServer();
48 48
49 resendDelay.init({ 49 resendDelay.init({
50 config: config, 50 config: config,
51 topupRequest: topupStatus, 51 topupRequest: topupStatus,
52 logger: logger 52 logger: logger
53 }); 53 });
54 } 54 }
55 55
56 function topupRequest(task) { 56 function topupRequest(task) {
57 aaa.insertTaskToMongoDb(task); 57 aaa.insertTaskToMongoDb(task);
58 alreadyPending.del(task.requestId); 58 alreadyPending.del(task.requestId);
59 59
60 getTaskFromHistory(task, function(err, archivedTask) { 60 getTaskFromHistory(task, function(err, archivedTask) {
61 putTaskToHistory(task); 61 putTaskToHistory(task);
62 62
63 if (archivedTask) { 63 if (archivedTask) {
64 logger.info('Task has been executed before, going to checkStatus', {task: task, archivedTask: archivedTask}); 64 logger.info('Task has been executed before, going to checkStatus', {task: task, archivedTask: archivedTask});
65 topupStatus(task); 65 topupStatus(task);
66 } else { 66 } else {
67 _topupRequest(task); 67 _topupRequest(task);
68 } 68 }
69 }); 69 });
70 } 70 }
71 71
72 function _topupRequest(task) { 72 function _topupRequest(task) {
73 73
74 var payload = composeTopupMessage( 74 var payload = composeTopupMessage(
75 config.h2h_out.pin, 75 config.h2h_out.pin,
76 task.remoteProduct, 76 task.remoteProduct,
77 task.destination, 77 task.destination,
78 task.requestId 78 task.requestId
79 ); 79 );
80 80
81 var reqOpts = { 81 var reqOpts = {
82 url: config.h2h_out.partner, 82 url: config.h2h_out.partner,
83 method: "POST", 83 method: "POST",
84 body: payload, 84 body: payload,
85 headers: { 85 headers: {
86 'Content-Type': 'text/xml', 86 'Content-Type': 'text/xml',
87 } 87 }
88 }; 88 };
89 89
90 logger.verbose('Requesting TOPUP to partner', {reqOpts: reqOpts, payload: payload}); 90 logger.verbose('Requesting TOPUP to partner', {reqOpts: reqOpts});
91 request(reqOpts, function (err, response, body) { 91 request(reqOpts, function (err, response, body) {
92 if (err) { 92 if (err) {
93 var msg = 'Error requesting TOPUP to partner: ' + err; 93 var msg = 'Error requesting TOPUP to partner: ' + err;
94 logger.warn(msg, {task: task, err: err}); 94 logger.warn(msg, {task: task, err: err});
95 callbackReport(task.requestId, '68', msg); 95 callbackReport(task.requestId, '68', msg);
96 return; 96 return;
97 } 97 }
98 98
99 logger.verbose('Got a direct response from TOPUP', {response: body, task: task}); 99 logger.verbose('Got a direct response from TOPUP', {response: body, task: task});
100 topupResponseHandler(body, task.requestId, callbackReport); 100 topupResponseHandler(body, task.requestId, callbackReport);
101 }); 101 });
102 } 102 }
103 103
104 function topupStatus(task) { 104 function topupStatus(task) {
105 var payload = composeTopupStatusMessage( 105 var payload = composeTopupStatusMessage(
106 config.h2h_out.pin, 106 config.h2h_out.pin,
107 task.requestId 107 task.requestId
108 ); 108 );
109 109
110 var reqOpts = { 110 var reqOpts = {
111 url: config.h2h_out.partner, 111 url: config.h2h_out.partner,
112 method: "POST", 112 method: "POST",
113 body: payload, 113 body: payload,
114 headers: { 114 headers: {
115 'Content-Type': 'text/xml', 115 'Content-Type': 'text/xml',
116 } 116 }
117 }; 117 };
118 118
119 logger.verbose('Requesting TOPUPSTATUS to partner', {reqOpts: reqOpts, payload: payload}); 119 logger.verbose('Requesting TOPUPSTATUS to partner', {reqOpts: reqOpts});
120 request(reqOpts, function (err, response, body) { 120 request(reqOpts, function (err, response, body) {
121 if (err) { 121 if (err) {
122 var msg = 'Error requesting TOPUPSTATUS to partner: ' + err; 122 var msg = 'Error requesting TOPUPSTATUS to partner: ' + err;
123 logger.warn(msg, {task: task, err: err}); 123 logger.warn(msg, {task: task, err: err});
124 callbackReport(task.requestId, '68', msg); 124 callbackReport(task.requestId, '68', msg);
125 return; 125 return;
126 } 126 }
127 127
128 logger.verbose('Got a direct response from TOPUPSTATUS', {response: body, task: task}); 128 logger.verbose('Got a direct response from TOPUPSTATUS', {response: body, task: task});
129 topupResponseHandler(body, task.requestId, callbackReport); 129 topupResponseHandler(body, task.requestId, callbackReport);
130 }); 130 });
131 } 131 }
132 132
133 function topupResponseHandler(xmlResponse, _requestId, cb) { 133 function topupResponseHandler(xmlResponse, _requestId, cb) {
134 var xmlParser = xml2js.parseString; 134 var xmlParser = xml2js.parseString;
135 xmlParser(xmlResponse, function(err, data) { 135 xmlParser(xmlResponse, function(err, data) {
136 var msg; 136 var msg;
137 var requestId; 137 var requestId;
138 var rc = '68'; 138 var rc = '68';
139 139
140 if (_requestId) { 140 if (_requestId) {
141 requestId = _requestId; 141 requestId = _requestId;
142 } 142 }
143 143
144 if (err) { 144 if (err) {
145 msg = 'Error parsing xml response: ' + err; 145 msg = 'Error parsing xml response: ' + err;
146 146
147 if (logger) { 147 if (logger) {
148 logger.warn(msg, {err: err, response: xmlResponse, task: task}); 148 logger.warn(msg, {err: err, response: xmlResponse, task: task});
149 } else { 149 } else {
150 console.log(msg); 150 console.log(msg);
151 } 151 }
152 } else { 152 } else {
153 153
154 logger.info('Response parsed', {data: data}); 154 logger.info('Response parsed', {data: data});
155 155
156 msg = getMessageFromResponse(data); 156 msg = getMessageFromResponse(data);
157 if (!msg) { 157 if (!msg) {
158 msg = 'Unknown message'; 158 msg = 'Unknown message';
159 } 159 }
160 160
161 var status = getStatusFromResponse(data); 161 var status = getStatusFromResponse(data);
162 if (status == '0') { 162 if (status == '0') {
163 163
164 rc = '00'; 164 rc = '00';
165 msg = modifyMessageWithSn(msg); 165 msg = modifyMessageWithSn(msg);
166 logger.verbose('Modify message on success message', {msg: msg}); 166 logger.verbose('Modify message on success message', {msg: msg});
167 167
168 } else if (status == '1') { 168 } else if (status == '1') {
169 rc = '68'; 169 rc = '68';
170 } else if (status == '2') { 170 } else if (status == '2') {
171 rc = '40'; 171 rc = '40';
172 } else if (status == '3') { 172 } else if (status == '3') {
173 rc = '40'; 173 rc = '40';
174 } else { 174 } else {
175 rc = '68'; 175 rc = '68';
176 msg = msg + '. Status is not valid ' + status; 176 msg = msg + '. Status is not valid ' + status;
177 } 177 }
178 178
179 var requestIdFromData = getRequestIdFromResponse(data); 179 var requestIdFromData = getRequestIdFromResponse(data);
180 if (requestIdFromData) { 180 if (requestIdFromData) {
181 requestId = requestIdFromData; 181 requestId = requestIdFromData;
182 } 182 }
183 } 183 }
184 184
185 cb(requestId, rc, msg, xmlResponse) 185 cb(requestId, rc, msg, xmlResponse)
186 }); 186 });
187 } 187 }
188 188
189 function callbackReport(requestId, responseCode, msg, rawResponse, dontResendDelay) { 189 function callbackReport(requestId, responseCode, msg, rawResponse, dontResendDelay) {
190 if (!requestId) { 190 if (!requestId) {
191 logger.warn('Undefined requestId, not sending callbackReport', {rc: responseCode, msg: msg, rawResponse: rawResponse}); 191 logger.warn('Undefined requestId, not sending callbackReport', {rc: responseCode, msg: msg, rawResponse: rawResponse});
192 return; 192 return;
193 } 193 }
194 194
195 if (responseCode != '68' || dontResendDelay) { 195 if (responseCode != '68' || dontResendDelay) {
196 resendDelay.cancel(requestId); 196 resendDelay.cancel(requestId);
197 } else { 197 } else {
198 getTaskFromHistory(requestId, function(err, archivedTask) { 198 getTaskFromHistory(requestId, function(err, archivedTask) {
199 if (archivedTask) { 199 if (archivedTask) {
200 resendDelay.register(archivedTask); 200 resendDelay.register(archivedTask);
201 } 201 }
202 }); 202 });
203 } 203 }
204 204
205 if (!alreadyPending.get(requestId) || responseCode != '68') { 205 if (!alreadyPending.get(requestId) || responseCode != '68') {
206 var responseObject = { 206 var responseObject = {
207 parsed: { 207 parsed: {
208 MESSAGE: msg 208 MESSAGE: msg
209 }, 209 },
210 raw: rawResponse 210 raw: rawResponse
211 211
212 } 212 }
213 _callbackReport(requestId, responseCode, msg, null, responseObject); 213 _callbackReport(requestId, responseCode, msg, null, responseObject);
214 } 214 }
215 alreadyPending.set(requestId, '68'); 215 alreadyPending.set(requestId, '68');
216 } 216 }
217 217
218 function getSnFromMessage(msg) { 218 function getSnFromMessage(msg) {
219 try { 219 try {
220 var matches = msg.match(/SN:\s*(\d+)/); 220 var matches = msg.match(/SN:\s*(\d+)/);
221 return matches[1]; 221 return matches[1];
222 } 222 }
223 catch(e) { 223 catch(e) {
224 return; 224 return;
225 } 225 }
226 } 226 }
227 227
228 function getStatusFromResponse(data) { 228 function getStatusFromResponse(data) {
229 try { 229 try {
230 return data.fm.status[0]; 230 return data.fm.status[0];
231 } 231 }
232 catch(e) { 232 catch(e) {
233 logger.warn('Exception on getStatusFromResponse: ' + e); 233 logger.warn('Exception on getStatusFromResponse: ' + e);
234 return; 234 return;
235 } 235 }
236 } 236 }
237 237
238 function getMessageFromResponse(data) { 238 function getMessageFromResponse(data) {
239 try { 239 try {
240 return data.fm.message[0]; 240 return data.fm.message[0];
241 } 241 }
242 catch(e) { 242 catch(e) {
243 logger.warn('Exception on getMessageFromResponse: ' + e); 243 logger.warn('Exception on getMessageFromResponse: ' + e);
244 return; 244 return;
245 } 245 }
246 } 246 }
247 247
248 function getRequestIdFromResponse(data) { 248 function getRequestIdFromResponse(data) {
249 try { 249 try {
250 return data.fm.refTrxid[0]; 250 return data.fm.refTrxid[0];
251 } 251 }
252 catch(e) { 252 catch(e) {
253 return; 253 return;
254 } 254 }
255 } 255 }
256 256
257 function modifyMessageWithSn(msg) { 257 function modifyMessageWithSn(msg) {
258 var sn = getSnFromMessage(msg); 258 var sn = getSnFromMessage(msg);
259 259
260 if (sn) { 260 if (sn) {
261 msg = 'SN=' + sn + '; ' + msg; 261 msg = 'SN=' + sn + '; ' + msg;
262 } 262 }
263 return msg; 263 return msg;
264 } 264 }
265 265
266 function composeTopupMessage(pin, product, destination, requestId) { 266 function composeTopupMessage(pin, product, destination, requestId) {
267 var data = {fm: { 267 var data = {fm: {
268 command: 'TOPUP', 268 command: 'TOPUP',
269 pin: pin, 269 pin: pin,
270 product: product, 270 product: product,
271 msisdn: destination, 271 msisdn: destination,
272 refTrxid: requestId 272 refTrxid: requestId
273 }}; 273 }};
274 274
275 return xmlBuilder.buildObject(data); 275 return xmlBuilder.buildObject(data);
276 } 276 }
277 277
278 function composeTopupStatusMessage(pin, requestId) { 278 function composeTopupStatusMessage(pin, requestId) {
279 var data = {fm: { 279 var data = {fm: {
280 command: 'TOPUPSTATUS', 280 command: 'TOPUPSTATUS',
281 pin: pin, 281 pin: pin,
282 refTrxid: requestId 282 refTrxid: requestId
283 }} 283 }}
284 284
285 return xmlBuilder.buildObject(data); 285 return xmlBuilder.buildObject(data);
286 } 286 }
287 287
288 function createServer() { 288 function createServer() {
289 var httpServer = http.createServer(function(request, response) { 289 var httpServer = http.createServer(function(request, response) {
290 290
291 logger.info('Got request from partner'); 291 logger.info('Got request from partner');
292 292
293 var body = ""; 293 var body = "";
294 req.on('data', function (chunk) { 294 req.on('data', function (chunk) {
295 body += chunk; 295 body += chunk;
296 }); 296 });
297 297
298 req.on('end', function () { 298 req.on('end', function () {
299 res.writeHead(200); 299 res.writeHead(200);
300 res.end('OK'); 300 res.end('OK');
301 301
302 topupResponseHandler(body, null, callbackReport); 302 topupResponseHandler(body, null, callbackReport);
303 303
304 }); 304 });
305 305
306 }); 306 });
307 307
308 httpServer.listen(config.h2h_out.listen_port, function() { 308 httpServer.listen(config.h2h_out.listen_port, function() {
309 logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port); 309 logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
310 }); 310 });
311 } 311 }
312 312
313 function createRedisClient(host, port) { 313 function createRedisClient(host, port) {
314 if (!host && !port) { 314 if (!host && !port) {
315 logger.info('Not creating redis client because unspecified host or port'); 315 logger.info('Not creating redis client because unspecified host or port');
316 return; 316 return;
317 } 317 }
318 318
319 try { 319 try {
320 redisClient = redis.createClient(port, host); 320 redisClient = redis.createClient(port, host);
321 } catch(err) { 321 } catch(err) {
322 logger.warn("Error creating redis client to " + host + ':' + port); 322 logger.warn("Error creating redis client to " + host + ':' + port);
323 } 323 }
324 } 324 }
325 325
326 function getTaskKey(task, chipInfo) { 326 function getTaskKey(task, chipInfo) {
327 var requestId; 327 var requestId;
328 328
329 if (typeof task === 'string') { 329 if (typeof task === 'string') {
330 requestId = task; 330 requestId = task;
331 } else { 331 } else {
332 try { 332 try {
333 requestId = task.requestId; 333 requestId = task.requestId;
334 } 334 }
335 catch(e) { 335 catch(e) {
336 logger.warn('Something wrong', {task: task}); 336 logger.warn('Something wrong', {task: task});
337 console.trace('Cekidot'); 337 console.trace('Cekidot');
338 process.exit(1); 338 process.exit(1);
339 } 339 }
340 340
341 } 341 }
342 342
343 if (!chipInfo && config && config.globals && config.globals.gateway_name) { 343 if (!chipInfo && config && config.globals && config.globals.gateway_name) {
344 chipInfo = config.globals.gateway_name; 344 chipInfo = config.globals.gateway_name;
345 } 345 }
346 346
347 return chipInfo + '.hitachi.rid:' + requestId; 347 return chipInfo + '.hitachi.rid:' + requestId;
348 } 348 }
349 349
350 350
351 function putTaskToHistory(task, cb) { 351 function putTaskToHistory(task, cb) {
352 if (Number(config.globals.no_dupe_check)) { 352 if (Number(config.globals.no_dupe_check)) {
353 if (cb) { cb(); } 353 if (cb) { cb(); }
354 return; 354 return;
355 } 355 }
356 var key = getTaskKey(task, config.globals.gateway_name); 356 var key = getTaskKey(task, config.globals.gateway_name);
357 logger.verbose('Saving task to history LRU', {key: key, task: task}); 357 logger.verbose('Saving task to history LRU', {key: key, task: task});
358 358
359 try { 359 try {
360 taskHistory.set(key, JSON.parse(JSON.stringify(task))); 360 taskHistory.set(key, JSON.parse(JSON.stringify(task)));
361 } catch (e) { } 361 } catch (e) { }
362 362
363 putTaskToRedis(task, cb); 363 putTaskToRedis(task, cb);
364 } 364 }
365 365
366 function putTaskToRedis(task, cb) { 366 function putTaskToRedis(task, cb) {
367 if (!redisClient) { 367 if (!redisClient) {
368 logger.verbose('Not saving to redis because of undefined redisClient') 368 logger.verbose('Not saving to redis because of undefined redisClient')
369 if (cb) { cb(); } 369 if (cb) { cb(); }
370 return; 370 return;
371 } 371 }
372 372
373 var key = getTaskKey(task, config.globals.gateway_name); 373 var key = getTaskKey(task, config.globals.gateway_name);
374 logger.verbose('Saving task to redis', {key: key, task: task}); 374 logger.verbose('Saving task to redis', {key: key, task: task});
375 375
376 redisClient.set(key, JSON.stringify(task), function() { 376 redisClient.set(key, JSON.stringify(task), function() {
377 redisClient.expire(key, 3600*24*30); 377 redisClient.expire(key, 3600*24*30);
378 if (cb) { 378 if (cb) {
379 cb(); 379 cb();
380 } 380 }
381 }); 381 });
382 } 382 }
383 383
384 function getTaskFromHistory(task, cb) { 384 function getTaskFromHistory(task, cb) {
385 logger.verbose('Getting task from history', {task: task}); 385 logger.verbose('Getting task from history', {task: task});
386 var key = getTaskKey(task, config.globals.gateway_name); 386 var key = getTaskKey(task, config.globals.gateway_name);
387 var archive = taskHistory.get(key); 387 var archive = taskHistory.get(key);
388 388
389 if (archive) { 389 if (archive) {
390 if (cb) { cb(null, archive); } 390 if (cb) { cb(null, archive); }
391 } 391 }
392 else { 392 else {
393 getTaskFromRedis(task, cb); 393 getTaskFromRedis(task, cb);
394 } 394 }
395 } 395 }
396 396
397 function getTaskFromRedis(task, cb) { 397 function getTaskFromRedis(task, cb) {
398 if (!redisClient) { 398 if (!redisClient) {
399 if (cb) { cb(null, null); } 399 if (cb) { cb(null, null); }
400 return; 400 return;
401 } 401 }
402 402
403 var key = getTaskKey(task, config.globals.gateway_name); 403 var key = getTaskKey(task, config.globals.gateway_name);
404 redisClient.get(key, function(err, result) { 404 redisClient.get(key, function(err, result) {
405 if (err) { 405 if (err) {
406 logger.warn('Error retrieving task from redis', {err: err}); 406 logger.warn('Error retrieving task from redis', {err: err});
407 cb(err, null); 407 cb(err, null);
408 return; 408 return;
409 } 409 }
410 410
411 var task; 411 var task;
412 try { 412 try {
413 task = JSON.parse(result); 413 task = JSON.parse(result);
414 } 414 }
415 catch(e) { 415 catch(e) {
416 logger.warn('Exception on parsing redis result as a json', {err: e}); 416 logger.warn('Exception on parsing redis result as a json', {err: e});
417 } 417 }
418 418
419 cb(null, task); 419 cb(null, task);
420 }) 420 })
421 } 421 }
422 422
423 423
424 exports.start = start; 424 exports.start = start;
425 exports.topupRequest = topupRequest; 425 exports.topupRequest = topupRequest;
426 exports.composeTopupMessage = composeTopupMessage; 426 exports.composeTopupMessage = composeTopupMessage;
427 exports.getSnFromMessage = getSnFromMessage; 427 exports.getSnFromMessage = getSnFromMessage;
428 exports.modifyMessageWithSn = modifyMessageWithSn; 428 exports.modifyMessageWithSn = modifyMessageWithSn;
429 429