Commit 090288ad17e733bb0add524d647cc2f1e7ef3954

Authored by Adhidarma Hadiwinoto
1 parent 240466132b
Exists in master

dumpStats

Showing 1 changed file with 10 additions and 0 deletions Inline Diff

1 var redis = require('redis'); 1 var redis = require('redis');
2 var moment = require('moment'); 2 var moment = require('moment');
3 var LRU = require('lru-cache'); 3 var LRU = require('lru-cache');
4 4
5 var config; 5 var config;
6 var logger; 6 var logger;
7 var partner; 7 var partner;
8 var imConfig; 8 var imConfig;
9 var redisClient; 9 var redisClient;
10 10
11 var resendHandlers = LRU({max: 2000, maxAge: 1000 * 3600 * 36}); 11 var resendHandlers = LRU({max: 2000, maxAge: 1000 * 3600 * 36});
12 12
13 function dumpStats() {
14 if (config.globals.auto_resend_on_delay_secs) {
15 logger.verbose('DUMP STATS', {
16 'resendHandlers:length': resendHandlers.length,
17 'resendHandlers:itemCount': resendHandlers.itemCount,
18 });
19 }
20 }
21
13 function init(options) { 22 function init(options) {
14 if (options && options.config) { 23 if (options && options.config) {
15 config = options.config; 24 config = options.config;
16 } 25 }
17 26
18 if (options && options.logger) { 27 if (options && options.logger) {
19 logger = options.logger; 28 logger = options.logger;
20 } 29 }
21 30
22 createRedisClient(config.globals.redis_host, config.globals.redis_port); 31 createRedisClient(config.globals.redis_host, config.globals.redis_port);
23 readImConfig(); 32 readImConfig();
33 setInterval(dumpStats, 1000 * 300);
24 } 34 }
25 35
26 function createRedisClient(host, port) { 36 function createRedisClient(host, port) {
27 try { 37 try {
28 redisClient = redis.createClient(port, host); 38 redisClient = redis.createClient(port, host);
29 } catch(err) { 39 } catch(err) {
30 logger.warn("Error creating redis client to " + host + ':' + port); 40 logger.warn("Error creating redis client to " + host + ':' + port);
31 } 41 }
32 } 42 }
33 43
34 function readImConfig(filename) { 44 function readImConfig(filename) {
35 45
36 if (!filename) { 46 if (!filename) {
37 filename = process.cwd() + '/config.im.json'; 47 filename = process.cwd() + '/config.im.json';
38 } 48 }
39 49
40 try { 50 try {
41 imConfig = require(filename); 51 imConfig = require(filename);
42 } 52 }
43 catch(e) { 53 catch(e) {
44 imConfig = {}; 54 imConfig = {};
45 } 55 }
46 56
47 logger.verbose('IM Config', {imConfig: imConfig}); 57 logger.verbose('IM Config', {imConfig: imConfig});
48 return imConfig; 58 return imConfig;
49 } 59 }
50 60
51 function getPatternFromMessage(message, pattern, patternMatchIndex) { 61 function getPatternFromMessage(message, pattern, patternMatchIndex) {
52 var re = new RegExp(pattern); 62 var re = new RegExp(pattern);
53 var matches = message.match(re); 63 var matches = message.match(re);
54 64
55 if (!matches) { 65 if (!matches) {
56 return null; 66 return null;
57 } 67 }
58 68
59 if (patternMatchIndex < matches.length) { 69 if (patternMatchIndex < matches.length) {
60 return matches[patternMatchIndex]; 70 return matches[patternMatchIndex];
61 } else { 71 } else {
62 return null; 72 return null;
63 } 73 }
64 } 74 }
65 75
66 function getPatternsFromMessage(message, patterns) { 76 function getPatternsFromMessage(message, patterns) {
67 var patternCount = patterns.length; 77 var patternCount = patterns.length;
68 for (var i = 0; i < patternCount; i++) { 78 for (var i = 0; i < patternCount; i++) {
69 79
70 var pattern = patterns[i]; 80 var pattern = patterns[i];
71 81
72 var result = getPatternFromMessage(message, pattern.pattern, pattern.matchIndex); 82 var result = getPatternFromMessage(message, pattern.pattern, pattern.matchIndex);
73 if (result) { 83 if (result) {
74 return result; 84 return result;
75 } 85 }
76 } 86 }
77 } 87 }
78 88
79 function getTaskKey(task, chipInfo, today) { 89 function getTaskKey(task, chipInfo, today) {
80 if (!chipInfo && config && config.globals && config.globals.gateway_name) { 90 if (!chipInfo && config && config.globals && config.globals.gateway_name) {
81 chipInfo = config.globals.gateway_name; 91 chipInfo = config.globals.gateway_name;
82 } 92 }
83 93
84 if (task.timestamp && !today) { 94 if (task.timestamp && !today) {
85 today = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYYMMDD'); 95 today = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYYMMDD');
86 } 96 }
87 97
88 return chipInfo + '.trx.date:' + today + '.rProduct:' + task.remoteProduct.toUpperCase() + '.dest:' + task.destination ; 98 return chipInfo + '.trx.date:' + today + '.rProduct:' + task.remoteProduct.toUpperCase() + '.dest:' + task.destination ;
89 } 99 }
90 100
91 function saveTask(task, cb) { 101 function saveTask(task, cb) {
92 var key = getTaskKey(task, config.globals.gateway_name); 102 var key = getTaskKey(task, config.globals.gateway_name);
93 logger.verbose('Saving task', {key: key, task: task}); 103 logger.verbose('Saving task', {key: key, task: task});
94 104
95 redisClient.set(key, JSON.stringify(task), function() { 105 redisClient.set(key, JSON.stringify(task), function() {
96 redisClient.expire(key, 3600*24); 106 redisClient.expire(key, 3600*24);
97 if (cb) { 107 if (cb) {
98 cb(); 108 cb();
99 } 109 }
100 }); 110 });
101 } 111 }
102 112
103 function getTask(remoteProduct, destination, cb) { 113 function getTask(remoteProduct, destination, cb) {
104 var dummyTask = { 114 var dummyTask = {
105 remoteProduct: remoteProduct, 115 remoteProduct: remoteProduct,
106 destination: destination, 116 destination: destination,
107 } 117 }
108 118
109 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD')); 119 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD'));
110 redisClient.get(key, function(err, result) { 120 redisClient.get(key, function(err, result) {
111 if (err) { 121 if (err) {
112 logger.verbose('getTask: task not found', {key: key, params: dummyTask}); 122 logger.verbose('getTask: task not found', {key: key, params: dummyTask});
113 123
114 cb(err, null); 124 cb(err, null);
115 return; 125 return;
116 } 126 }
117 127
118 var task = {}; 128 var task = {};
119 129
120 try { 130 try {
121 task = JSON.parse(result); 131 task = JSON.parse(result);
122 } 132 }
123 catch(e) { 133 catch(e) {
124 logger.warn('getTask: Can not parse result', {key: key, params: dummyTask, data: result}); 134 logger.warn('getTask: Can not parse result', {key: key, params: dummyTask, data: result});
125 err = "Can not parse result" 135 err = "Can not parse result"
126 } 136 }
127 cb(err, task); 137 cb(err, task);
128 }); 138 });
129 } 139 }
130 140
131 function deleteTask(remoteProduct, destination) { 141 function deleteTask(remoteProduct, destination) {
132 var dummyTask = { 142 var dummyTask = {
133 remoteProduct: remoteProduct, 143 remoteProduct: remoteProduct,
134 destination: destination, 144 destination: destination,
135 } 145 }
136 146
137 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD')); 147 var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD'));
138 148
139 try { 149 try {
140 redisClient.del(key); 150 redisClient.del(key);
141 } 151 }
142 catch(e) {}; 152 catch(e) {};
143 } 153 }
144 154
145 function createMessage(pattern, keywords) { 155 function createMessage(pattern, keywords) {
146 var msg = pattern; 156 var msg = pattern;
147 157
148 for (var key in keywords) { 158 for (var key in keywords) {
149 msg = msg.replace('[' + key + ']', keywords[key]); 159 msg = msg.replace('[' + key + ']', keywords[key]);
150 } 160 }
151 return msg; 161 return msg;
152 } 162 }
153 163
154 function getRemoteProductFromMessage(msg) { 164 function getRemoteProductFromMessage(msg) {
155 return getPatternsFromMessage(msg, imConfig.product_patterns); 165 return getPatternsFromMessage(msg, imConfig.product_patterns);
156 } 166 }
157 167
158 function getDestinationFromMessage(msg) { 168 function getDestinationFromMessage(msg) {
159 return getPatternsFromMessage(msg, imConfig.destination_patterns); 169 return getPatternsFromMessage(msg, imConfig.destination_patterns);
160 } 170 }
161 171
162 function getSnFromMessage(msg) { 172 function getSnFromMessage(msg) {
163 return getPatternsFromMessage(msg, imConfig.sn_patterns); 173 return getPatternsFromMessage(msg, imConfig.sn_patterns);
164 } 174 }
165 175
166 function getRcFromMessage(msg) { 176 function getRcFromMessage(msg) {
167 var rcs = imConfig.response_codes; 177 var rcs = imConfig.response_codes;
168 var rcsCount = rcs.length; 178 var rcsCount = rcs.length;
169 179
170 for (var i = 0; i < rcsCount; i++) { 180 for (var i = 0; i < rcsCount; i++) {
171 181
172 var item = rcs[i]; 182 var item = rcs[i];
173 var re = new RegExp(item.pattern); 183 var re = new RegExp(item.pattern);
174 if (msg.search(re) != -1) { 184 if (msg.search(re) != -1) {
175 return item.rc; 185 return item.rc;
176 } 186 }
177 187
178 } 188 }
179 return '68'; 189 return '68';
180 } 190 }
181 191
182 function isAllowedFrom(sender) { 192 function isAllowedFrom(sender) {
183 if (!config || !config.h2h_out || !config.h2h_out.allowed_response_from) { 193 if (!config || !config.h2h_out || !config.h2h_out.allowed_response_from) {
184 return true; 194 return true;
185 } 195 }
186 196
187 whitelist = config.h2h_out.allowed_response_from.split(','); 197 whitelist = config.h2h_out.allowed_response_from.split(',');
188 whitelistCount = whitelist.length; 198 whitelistCount = whitelist.length;
189 199
190 for(var i=0; i<whitelistCount; i++) { 200 for(var i=0; i<whitelistCount; i++) {
191 if (sender == whitelist[i]) { 201 if (sender == whitelist[i]) {
192 return true; 202 return true;
193 } 203 }
194 } 204 }
195 205
196 return false; 206 return false;
197 } 207 }
198 208
199 function checkForSameDayDuplicate(task, cbNoDupe, cbDupe, cbDupeWithSameReqId) { 209 function checkForSameDayDuplicate(task, cbNoDupe, cbDupe, cbDupeWithSameReqId) {
200 getTask(task.remoteProduct, task.destination, function(err, archivedTask) { 210 getTask(task.remoteProduct, task.destination, function(err, archivedTask) {
201 if (err) { 211 if (err) {
202 logger.warn('Error on checking same day duplicate', {task: task}); 212 logger.warn('Error on checking same day duplicate', {task: task});
203 cbNoDupe(task); 213 cbNoDupe(task);
204 return; 214 return;
205 } 215 }
206 216
207 if (archivedTask && archivedTask.requestId) { 217 if (archivedTask && archivedTask.requestId) {
208 if (cbDupeWithSameReqId && task.requestId == archivedTask.requestId) { 218 if (cbDupeWithSameReqId && task.requestId == archivedTask.requestId) {
209 logger.verbose('Duplicate trx on same day with same requestId', {task: task}); 219 logger.verbose('Duplicate trx on same day with same requestId', {task: task});
210 cbDupeWithSameReqId(task, archivedTask); 220 cbDupeWithSameReqId(task, archivedTask);
211 return; 221 return;
212 } 222 }
213 223
214 logger.verbose('Duplicate trx on same day', {task: task, archivedTask: archivedTask}); 224 logger.verbose('Duplicate trx on same day', {task: task, archivedTask: archivedTask});
215 cbDupe(task, archivedTask); 225 cbDupe(task, archivedTask);
216 return; 226 return;
217 } 227 }
218 228
219 cbNoDupe(task); 229 cbNoDupe(task);
220 }); 230 });
221 } 231 }
222 232
223 function registerResendDelay(task) { 233 function registerResendDelay(task) {
224 if (!task.requestId) { 234 if (!task.requestId) {
225 logger.warn('Invalid task on resendDelay') 235 logger.warn('Invalid task on resendDelay')
226 return; 236 return;
227 } 237 }
228 238
229 if (!config || !config.globals || !config.globals.auto_resend_on_delay_secs) { 239 if (!config || !config.globals || !config.globals.auto_resend_on_delay_secs) {
230 return; 240 return;
231 } 241 }
232 242
233 if (!partner || !partner.topupRequest) { 243 if (!partner || !partner.topupRequest) {
234 logger.warn('Skip request resend delay because partner.topupRequest is not exists'); 244 logger.warn('Skip request resend delay because partner.topupRequest is not exists');
235 return; 245 return;
236 } 246 }
237 247
238 var retry = 10; 248 var retry = 10;
239 var oldHandler = resendHandlers.get(task.requestId); 249 var oldHandler = resendHandlers.get(task.requestId);
240 if (oldHandler) { 250 if (oldHandler) {
241 retry = oldHandler.retry - 1; 251 retry = oldHandler.retry - 1;
242 } 252 }
243 253
244 if (retry <= 0) { 254 if (retry <= 0) {
245 logger.verbose('Resend delay retry exceeded', {task: task}); 255 logger.verbose('Resend delay retry exceeded', {task: task});
246 cancelResendDelay(task); 256 cancelResendDelay(task);
247 return; 257 return;
248 } 258 }
249 259
250 logger.info('Resending task request', {task: task}); 260 logger.info('Resending task request', {task: task});
251 var handlerData = { 261 var handlerData = {
252 handler: setTimeout(partner.topupRequest, config.globals.auto_resend_on_delay_secs, task), 262 handler: setTimeout(partner.topupRequest, config.globals.auto_resend_on_delay_secs, task),
253 task: task, 263 task: task,
254 retry: retry 264 retry: retry
255 } 265 }
256 266
257 resendHandlers.set(task.requestId, handlerData); 267 resendHandlers.set(task.requestId, handlerData);
258 } 268 }
259 269
260 function cancelResendDelay(task) { 270 function cancelResendDelay(task) {
261 if (!task || !task.requestId) { 271 if (!task || !task.requestId) {
262 logger.warn('Invalid task on cancelResendDelay'); 272 logger.warn('Invalid task on cancelResendDelay');
263 return; 273 return;
264 } 274 }
265 275
266 var oldHandler = resendHandlers.get(task.requestId); 276 var oldHandler = resendHandlers.get(task.requestId);
267 if (!oldHandler) { 277 if (!oldHandler) {
268 return; 278 return;
269 } 279 }
270 280
271 logger.verbose('Canceling resend delay', {task: task}); 281 logger.verbose('Canceling resend delay', {task: task});
272 282
273 try { 283 try {
274 if (oldHandler.handler) { 284 if (oldHandler.handler) {
275 clearTimeout(oldHandler.handler); 285 clearTimeout(oldHandler.handler);
276 } 286 }
277 } 287 }
278 catch(e) {}; 288 catch(e) {};
279 289
280 try { 290 try {
281 resendHandlers.del(task.requestId); 291 resendHandlers.del(task.requestId);
282 } 292 }
283 catch(e) {}; 293 catch(e) {};
284 } 294 }
285 295
286 exports.init = init; 296 exports.init = init;
287 exports.start = init; 297 exports.start = init;
288 exports.getPatternFromMessage = getPatternFromMessage; 298 exports.getPatternFromMessage = getPatternFromMessage;
289 exports.getPatternsFromMessage = getPatternsFromMessage; 299 exports.getPatternsFromMessage = getPatternsFromMessage;
290 exports.saveTask = saveTask; 300 exports.saveTask = saveTask;
291 exports.getTask = getTask; 301 exports.getTask = getTask;
292 exports.readImConfig = readImConfig; 302 exports.readImConfig = readImConfig;
293 exports.createMessage = createMessage; 303 exports.createMessage = createMessage;
294 exports.getRemoteProductFromMessage = getRemoteProductFromMessage; 304 exports.getRemoteProductFromMessage = getRemoteProductFromMessage;
295 exports.getDestinationFromMessage = getDestinationFromMessage; 305 exports.getDestinationFromMessage = getDestinationFromMessage;
296 exports.getRcFromMessage = getRcFromMessage; 306 exports.getRcFromMessage = getRcFromMessage;
297 exports.getSnFromMessage = getSnFromMessage; 307 exports.getSnFromMessage = getSnFromMessage;
298 exports.isAllowedFrom = isAllowedFrom; 308 exports.isAllowedFrom = isAllowedFrom;
299 exports.checkForSameDayDuplicate = checkForSameDayDuplicate; 309 exports.checkForSameDayDuplicate = checkForSameDayDuplicate;
300 exports.deleteTask = deleteTask; 310 exports.deleteTask = deleteTask;
301 exports.registerResendDelay = registerResendDelay; 311 exports.registerResendDelay = registerResendDelay;
302 exports.cancelResendDelay = cancelResendDelay; 312 exports.cancelResendDelay = cancelResendDelay;
303 313