Commit 0b9b60b118bb18ca6d9b41ad54e138c59e76ed20

Authored by Adhidarma Hadiwinoto
1 parent 97a8eb629f
Exists in master

penanganan ipv6 hybrid remoteAddress

Showing 1 changed file with 8 additions and 7 deletions Inline Diff

1 var xmlrpc = require('xmlrpc'); 1 var xmlrpc = require('xmlrpc');
2 var request = require('request'); 2 var request = require('request');
3 var neoxmlinutil = require('./neoxmlinutil'); 3 var neoxmlinutil = require('./neoxmlinutil');
4 var http = require('http'); 4 var http = require('http');
5 var https = require('https'); 5 var https = require('https');
6 var fs = require('fs'); 6 var fs = require('fs');
7 var xml2js = new require('xml2js'); 7 var xml2js = new require('xml2js');
8 var xml2jsParser = require('xml2js').parseString; 8 var xml2jsParser = require('xml2js').parseString;
9 var xml2jsBuilder = new xml2js.Builder(); 9 var xml2jsBuilder = new xml2js.Builder();
10 var url = require("url"); 10 var url = require("url");
11 var strftime = require('strftime'); 11 var strftime = require('strftime');
12 12
13 var options; 13 var options;
14 var config; 14 var config;
15 var logger; 15 var logger;
16 16
17 var server; 17 var server;
18 18
19 var delayBeforeRetryTopUpReport = 10 * 1000; 19 var delayBeforeRetryTopUpReport = 10 * 1000;
20 var maxTopUpReportRetry = 5; 20 var maxTopUpReportRetry = 5;
21 21
22 function start(_options) { 22 function start(_options) {
23 options = _options; 23 options = _options;
24 24
25 if (options.config) { 25 if (options.config) {
26 config = options.config; 26 config = options.config;
27 } 27 }
28 else { 28 else {
29 config = require("./config.json"); 29 config = require("./config.json");
30 } 30 }
31 31
32 if (options.logger) { 32 if (options.logger) {
33 logger = options.logger; 33 logger = options.logger;
34 } 34 }
35 else { 35 else {
36 logger = console; 36 logger = console;
37 } 37 }
38 38
39 createResponseServer(); 39 createResponseServer();
40 40
41 createDiyHttpXmlRpcServer(); 41 createDiyHttpXmlRpcServer();
42 //createXmlRpcServer() 42 //createXmlRpcServer()
43 //createExpressXmlRpcServer(); 43 //createExpressXmlRpcServer();
44 44
45 try { 45 try {
46 http.globalAgent.maxSockets = Infinity; 46 http.globalAgent.maxSockets = Infinity;
47 } 47 }
48 catch(e) { 48 catch(e) {
49 logger.warn('Error setting http.globalAgent.maxSockets = Infinity', {err: e}); 49 logger.warn('Error setting http.globalAgent.maxSockets = Infinity', {err: e});
50 } 50 }
51 51
52 } 52 }
53 53
54 function getXmlRpcParam(values) { 54 function getXmlRpcParam(values) {
55 try { 55 try {
56 56
57 var count = values.length 57 var count = values.length
58 var result = {}; 58 var result = {};
59 for (var i = 0; i < count; i++) { 59 for (var i = 0; i < count; i++) {
60 var value = values[i]; 60 var value = values[i];
61 61
62 var keys = Object.keys(value.value[0]); 62 var keys = Object.keys(value.value[0]);
63 var firstKey = keys[0]; 63 var firstKey = keys[0];
64 result[value.name[0]] = value.value[0][firstKey][0]; 64 result[value.name[0]] = value.value[0][firstKey][0];
65 } 65 }
66 66
67 return result; 67 return result;
68 68
69 } 69 }
70 catch(err) { 70 catch(err) {
71 return null; 71 return null;
72 } 72 }
73 } 73 }
74 74
75 function createDiyHttpXmlRpcServer() { 75 function createDiyHttpXmlRpcServer() {
76 var serverOptions = { 76 var serverOptions = {
77 key: fs.readFileSync('./server.key'), 77 key: fs.readFileSync('./server.key'),
78 cert: fs.readFileSync('./server.crt') 78 cert: fs.readFileSync('./server.crt')
79 } 79 }
80 80
81 var httpServer = https.createServer(serverOptions, function(req, res) { 81 var httpServer = https.createServer(serverOptions, function(req, res) {
82 var remoteAddress = req.connection.remoteAddress.replace(/^::ffff:/, '');
82 83
83 logger.verbose("Incoming connection from " + req.connection.remoteAddress); 84 logger.verbose("Incoming connection from " + remoteAddress);
84 85
85 var body = ""; 86 var body = "";
86 87
87 req.on('data', function (chunk) { 88 req.on('data', function (chunk) {
88 body += chunk; 89 body += chunk;
89 }); 90 });
90 91
91 req.on('end', function () { 92 req.on('end', function () {
92 93
93 xml2jsParser(body, function(err, message) { 94 xml2jsParser(body, function(err, message) {
94 95
95 if (err) { 96 if (err) {
96 logger.warn('Got XMLRPC invalid XML request body from ' + req.connection.remoteAddress, {body: body, err: err}); 97 logger.warn('Got XMLRPC invalid XML request body from ' + remoteAddress, {body: body, err: err});
97 res.end('Invalid XMLRPC request'); 98 res.end('Invalid XMLRPC request');
98 return; 99 return;
99 } 100 }
100 101
101 var method; 102 var method;
102 var _params; 103 var _params;
103 104
104 try { 105 try {
105 method = message.methodCall.methodName[0]; 106 method = message.methodCall.methodName[0];
106 _params = message.methodCall.params[0].param[0].value[0].struct[0].member; 107 _params = message.methodCall.params[0].param[0].value[0].struct[0].member;
107 } 108 }
108 catch(errSelectMethod) { 109 catch(errSelectMethod) {
109 logger.warn('Failed to get method and params on request from ' + req.connection.remoteAddress); 110 logger.warn('Failed to get method and params on request from ' + remoteAddress);
110 res.end('Invalid XMLRPC message') 111 res.end('Invalid XMLRPC message')
111 return; 112 return;
112 } 113 }
113 114
114 params = getXmlRpcParam(_params); 115 var params = getXmlRpcParam(_params);
115 logger.info('Got XMLRPC request from ' + req.connection.remoteAddress, {method: method, params: params}); 116 logger.info('Got XMLRPC request from ' + remoteAddress, {method: method, params: params});
116 117
117 if (method == 'topUpRequest') { 118 if (method == 'topUpRequest') {
118 119
119 sendTopUpRequestToMaster(params, req.connection.remoteAddress, function(forwardError) { 120 sendTopUpRequestToMaster(params, remoteAddress, function(forwardError) {
120 if (forwardError) { 121 if (forwardError) {
121 immediateReply(params, res, '40', forwardError.toString()); 122 immediateReply(params, res, '40', forwardError.toString());
122 } else { 123 } else {
123 immediateReply(params, res, '68'); 124 immediateReply(params, res, '68');
124 } 125 }
125 }); 126 });
126 127
127 } 128 }
128 else if (method == 'topUpInquiry') { 129 else if (method == 'topUpInquiry') {
129 130
130 sendTopUpInquryToMaster(params, req.connection.remoteAddress, res); 131 sendTopUpInquryToMaster(params, remoteAddress, res);
131 132
132 } 133 }
133 else { 134 else {
134 res.end('Invalid method'); 135 res.end('Invalid method');
135 } 136 }
136 137
137 138
138 }) 139 })
139 }); 140 });
140 141
141 }); 142 });
142 143
143 httpServer.listen(config.server_options.port, function() { 144 httpServer.listen(config.server_options.port, function() {
144 logger.info('HTTP XMLRPC listen on port ' + config.server_options.port); 145 logger.info('HTTP XMLRPC listen on port ' + config.server_options.port);
145 }); 146 });
146 } 147 }
147 148
148 function composeXmlRpcResponse(param) { 149 function composeXmlRpcResponse(param) {
149 150
150 var values = []; 151 var values = [];
151 var keys = Object.keys(param); 152 var keys = Object.keys(param);
152 var keysCount = keys.length; 153 var keysCount = keys.length;
153 154
154 for (var i = 0; i < keysCount; i++) { 155 for (var i = 0; i < keysCount; i++) {
155 var key = keys[i]; 156 var key = keys[i];
156 var value = { 157 var value = {
157 name: key, 158 name: key,
158 value: { 159 value: {
159 string: param[key] 160 string: param[key]
160 } 161 }
161 } 162 }
162 values.push(value); 163 values.push(value);
163 } 164 }
164 165
165 var data = { 166 var data = {
166 methodResponse: { 167 methodResponse: {
167 params: { 168 params: {
168 param: { 169 param: {
169 value: { 170 value: {
170 struct: { 171 struct: {
171 member: values 172 member: values
172 } 173 }
173 } 174 }
174 } 175 }
175 } 176 }
176 } 177 }
177 } 178 }
178 179
179 //logger.info(JSON.stringify(data)); 180 //logger.info(JSON.stringify(data));
180 181
181 return xml2jsBuilder.buildObject(data); 182 return xml2jsBuilder.buildObject(data);
182 } 183 }
183 184
184 function immediateReply(param, requestResponse, responseCode, message) { 185 function immediateReply(param, requestResponse, responseCode, message) {
185 186
186 if (!responseCode) { 187 if (!responseCode) {
187 responseCode = '68'; 188 responseCode = '68';
188 } 189 }
189 190
190 if (!message) { 191 if (!message) {
191 message = "Sementara tidak dapat diproses."; 192 message = "Sementara tidak dapat diproses.";
192 } 193 }
193 194
194 if (responseCode == '68') { 195 if (responseCode == '68') {
195 message = 'ISI ' 196 message = 'ISI '
196 + param.NOM.toUpperCase() 197 + param.NOM.toUpperCase()
197 + ' KE ' 198 + ' KE '
198 + param.NOHP 199 + param.NOHP
199 + ', Transaksi anda sedang diproses' 200 + ', Transaksi anda sedang diproses'
200 } 201 }
201 202
202 var responseData = { 203 var responseData = {
203 'RESPONSECODE': responseCode, 204 'RESPONSECODE': responseCode,
204 'REQUESTID': param.REQUESTID, 205 'REQUESTID': param.REQUESTID,
205 'MESSAGE': message, 206 'MESSAGE': message,
206 'TRANSACTIONID': '0', 207 'TRANSACTIONID': '0',
207 } 208 }
208 209
209 210
210 var responseBody = composeXmlRpcResponse(responseData) 211 var responseBody = composeXmlRpcResponse(responseData)
211 logger.info("Sending immediateReply response", {responseData: responseData}); 212 logger.info("Sending immediateReply response", {responseData: responseData});
212 213
213 requestResponse.writeHead(200, {'Content-Type': 'text/xml'}); 214 requestResponse.writeHead(200, {'Content-Type': 'text/xml'});
214 requestResponse.end(responseBody); 215 requestResponse.end(responseBody);
215 } 216 }
216 217
217 function composeMessage(params, remoteAddress) { 218 function composeMessage(params, remoteAddress) {
218 try { 219 try {
219 var nom = params.NOM.replace(/\./g, '').trim(); 220 var nom = params.NOM.replace(/\./g, '').trim();
220 var destination = params.NOHP.replace(/\./g, '').trim(); 221 var destination = params.NOHP.replace(/\./g, '').trim();
221 var pin = params.PIN.replace(/\./g, '').trim(); 222 var pin = params.PIN.replace(/\./g, '').trim();
222 var requestId = params.REQUESTID.replace(/\./g, '').trim(); 223 var requestId = params.REQUESTID.replace(/\./g, '').trim();
223 224
224 return 'MI.' + nom + '."' + destination + '".' + pin + '.' + requestId + '.NOTRUST."' + remoteAddress + '"'; 225 return 'MI.' + nom + '."' + destination + '".' + pin + '.' + requestId + '.NOTRUST."' + remoteAddress + '"';
225 } 226 }
226 catch(err) { 227 catch(err) {
227 return; 228 return;
228 } 229 }
229 230
230 231
231 } 232 }
232 233
233 function inquiryReply(responseCode, message, responseToClient) { 234 function inquiryReply(responseCode, message, responseToClient) {
234 var responseData = { 235 var responseData = {
235 'RESPONSECODE': responseCode, 236 'RESPONSECODE': responseCode,
236 'MESSAGE': message 237 'MESSAGE': message
237 } 238 }
238 239
239 var responseBody = composeXmlRpcResponse(responseData) 240 var responseBody = composeXmlRpcResponse(responseData)
240 logger.info("Sending inquiry response", {responseData: responseData}); 241 logger.info("Sending inquiry response", {responseData: responseData});
241 242
242 responseToClient.writeHead(200, {'Content-Type': 'text/xml'}); 243 responseToClient.writeHead(200, {'Content-Type': 'text/xml'});
243 responseToClient.end(responseBody); 244 responseToClient.end(responseBody);
244 } 245 }
245 246
246 function parseTopUpInquiryResponse(raw) { 247 function parseTopUpInquiryResponse(raw) {
247 var tokens = raw.split('$'); 248 var tokens = raw.split('$');
248 if (tokens.length < 2) { 249 if (tokens.length < 2) {
249 return { 250 return {
250 responseCode: '68', 251 responseCode: '68',
251 message: 'Gagal parsing hasil inquiry' 252 message: 'Gagal parsing hasil inquiry'
252 } 253 }
253 } 254 }
254 255
255 var responseCode = tokens[0]; 256 var responseCode = tokens[0];
256 var message = ''; 257 var message = '';
257 258
258 for (var i = 1; i < tokens.length; i++) { 259 for (var i = 1; i < tokens.length; i++) {
259 message += '$' + tokens[i]; 260 message += '$' + tokens[i];
260 } 261 }
261 262
262 return { 263 return {
263 responseCode: responseCode, 264 responseCode: responseCode,
264 message: message.replace('$', '') 265 message: message.replace('$', '')
265 } 266 }
266 } 267 }
267 268
268 function sendTopUpInquryToMaster(params, remoteAddress, responseToClient) { 269 function sendTopUpInquryToMaster(params, remoteAddress, responseToClient) {
269 if (!config.inquiry_url) { 270 if (!config.inquiry_url) {
270 inquiryReply('68', 'Inquiry server tidak terdaftar'); 271 inquiryReply('68', 'Inquiry server tidak terdaftar');
271 return; 272 return;
272 } 273 }
273 274
274 var requestOpts = { 275 var requestOpts = {
275 url: config.inquiry_url, 276 url: config.inquiry_url,
276 qs: { 277 qs: {
277 REQUESTID: params.REQUESTID, 278 REQUESTID: params.REQUESTID,
278 MSISDN: param.MSISDN, 279 MSISDN: param.MSISDN,
279 PIN: params.PIN, 280 PIN: params.PIN,
280 NO_HP: params.NO_HP, 281 NO_HP: params.NO_HP,
281 TRUST: 'NO_TRUST', 282 TRUST: 'NO_TRUST',
282 IP_ADDR: remoteAddress 283 IP_ADDR: remoteAddress
283 } 284 }
284 }; 285 };
285 286
286 request(requestOpts, function(requestError, response, body) { 287 request(requestOpts, function(requestError, response, body) {
287 288
288 if (requestError) { 289 if (requestError) {
289 logger.warn('Error requesting to inquiry server: ' + requestError); 290 logger.warn('Error requesting to inquiry server: ' + requestError);
290 inquiryReply('68', 'Gagal konek ke inquiry server', responseToClient); 291 inquiryReply('68', 'Gagal konek ke inquiry server', responseToClient);
291 return; 292 return;
292 } 293 }
293 294
294 logger.info('Got response from inquiry server', {body: body, requestOpts: requestOpts}); 295 logger.info('Got response from inquiry server', {body: body, requestOpts: requestOpts});
295 var params = parseTopUpInquiryResponse(body); 296 var params = parseTopUpInquiryResponse(body);
296 inquiryReply(params.responseCode, params.message, responseToClient); 297 inquiryReply(params.responseCode, params.message, responseToClient);
297 }) 298 })
298 } 299 }
299 300
300 function sendTopUpRequestToMaster(param, remoteAddress, callback) { 301 function sendTopUpRequestToMaster(param, remoteAddress, callback) {
301 302
302 /* 303 /*
303 var smscidSuffix = '99999999999999' + String(Math.round(Math.random() * 99999999999999)); 304 var smscidSuffix = '99999999999999' + String(Math.round(Math.random() * 99999999999999));
304 var smscid = 'XML1' + smscidSuffix.slice(-13); 305 var smscid = 'XML1' + smscidSuffix.slice(-13);
305 */ 306 */
306 307
307 //var smscid = 'XML' + '12345' + strftime('%H%M%S%L'); 308 //var smscid = 'XML' + '12345' + strftime('%H%M%S%L');
308 var smscid = config.smscid;// + Math.round(Math.random() * 9999999999999); 309 var smscid = config.smscid;// + Math.round(Math.random() * 9999999999999);
309 310
310 var message = composeMessage(param, remoteAddress); 311 var message = composeMessage(param, remoteAddress);
311 if (!message) { 312 if (!message) {
312 logger.warn('Invalid message for sendToMaster', {param: param}); 313 logger.warn('Invalid message for sendToMaster', {param: param});
313 return; 314 return;
314 } 315 }
315 316
316 var requestOpts = { 317 var requestOpts = {
317 url: config.master_url, 318 url: config.master_url,
318 qs: { 319 qs: {
319 PhoneNumber: param.MSISDN, 320 PhoneNumber: param.MSISDN,
320 'Text': message, 321 'Text': message,
321 Res_Port: config.res_port, 322 Res_Port: config.res_port,
322 Smscid: smscid 323 Smscid: smscid
323 } 324 }
324 }; 325 };
325 326
326 if (config.res_ip) { 327 if (config.res_ip) {
327 requestOpts.qs.ip_addr = config.res_ip; 328 requestOpts.qs.ip_addr = config.res_ip;
328 } 329 }
329 330
330 logger.info('Forward request to master', {requestOpts: requestOpts}); 331 logger.info('Forward request to master', {requestOpts: requestOpts});
331 332
332 request(requestOpts, function(requestError, response, body) { 333 request(requestOpts, function(requestError, response, body) {
333 334
334 if (requestError) { 335 if (requestError) {
335 logger.warn('Error requesting to master: ' + requestError); 336 logger.warn('Error requesting to master: ' + requestError);
336 } else { 337 } else {
337 logger.info('Got response from master', {body: body, requestOpts: requestOpts}); 338 logger.info('Got response from master', {body: body, requestOpts: requestOpts});
338 } 339 }
339 340
340 callback(requestError); 341 callback(requestError);
341 }) 342 })
342 343
343 } 344 }
344 345
345 function sendReply(response) { 346 function sendReply(response) {
346 /* 347 /*
347 var requestId = neoxmlinutil.getRequestIdFromResponseMessage(response.text); 348 var requestId = neoxmlinutil.getRequestIdFromResponseMessage(response.text);
348 349
349 if (!requestId) { 350 if (!requestId) {
350 logger.warn('No request id found, skipping'); 351 logger.warn('No request id found, skipping');
351 return; 352 return;
352 } 353 }
353 */ 354 */
354 355
355 var params = { 356 var params = {
356 REQUESTID: response.requestid, 357 REQUESTID: response.requestid,
357 MSISDN: response.PhoneNumber, 358 MSISDN: response.PhoneNumber,
358 RESPONSECODE: response.resp_code, 359 RESPONSECODE: response.resp_code,
359 MESSAGE: response.text, 360 MESSAGE: response.text,
360 } 361 }
361 362
362 if (response.new_sn) { 363 if (response.new_sn) {
363 params.SN = response.new_sn.replace(/^SN=/, ''); 364 params.SN = response.new_sn.replace(/^SN=/, '');
364 } 365 }
365 366
366 if (response.new_ending_balance) { 367 if (response.new_ending_balance) {
367 params.BALANCE = response.new_ending_balance; 368 params.BALANCE = response.new_ending_balance;
368 } 369 }
369 370
370 if (response.new_price) { 371 if (response.new_price) {
371 params.PRICE = response.new_price; 372 params.PRICE = response.new_price;
372 } 373 }
373 374
374 logger.info('sendReply', {params: params}); 375 logger.info('sendReply', {params: params});
375 376
376 neoxmlinutil.getReverseUrl(response.PhoneNumber, function(err, reverseUrls) { 377 neoxmlinutil.getReverseUrl(response.PhoneNumber, function(err, reverseUrls) {
377 if (err) { 378 if (err) {
378 logger.warn('Fail to get reverse urls, skipping'); 379 logger.warn('Fail to get reverse urls, skipping');
379 return; 380 return;
380 } 381 }
381 382
382 if (reverseUrls.length <= 0) { 383 if (reverseUrls.length <= 0) {
383 logger.warn('No reverse urls found, skipping'); 384 logger.warn('No reverse urls found, skipping');
384 return; 385 return;
385 } 386 }
386 387
387 sendTopUpReport(reverseUrls, params, 0, 4); 388 sendTopUpReport(reverseUrls, params, 0, 4);
388 }); 389 });
389 } 390 }
390 391
391 function errorOnTopUpReport(topUpReportError, debugInfo) { 392 function errorOnTopUpReport(topUpReportError, debugInfo) {
392 var hasError = false; 393 var hasError = false;
393 394
394 if (!topUpReportError) { 395 if (!topUpReportError) {
395 return false; 396 return false;
396 } 397 }
397 398
398 try { 399 try {
399 if (topUpReportError.body) { 400 if (topUpReportError.body) {
400 logger.verbose('errorOnTopUpReport response body: ' + topUpReportError.body, {req: debugInfo}); 401 logger.verbose('errorOnTopUpReport response body: ' + topUpReportError.body, {req: debugInfo});
401 } 402 }
402 403
403 if (topUpReportError.res && topUpReportError.res.statusCode && topUpReportError.res.statusCode != '200') { 404 if (topUpReportError.res && topUpReportError.res.statusCode && topUpReportError.res.statusCode != '200') {
404 logger.verbose('Partner response with status code:' + topUpReportError.res.statusCode, {req: debugInfo}); 405 logger.verbose('Partner response with status code:' + topUpReportError.res.statusCode, {req: debugInfo});
405 406
406 if (topUpReportError.res.statusCode != '200') { 407 if (topUpReportError.res.statusCode != '200') {
407 logger.warn('Going to resend topUpReport because status code is not 200 (' + topUpReportError.res.statusCode + ')', {req: debugInfo}); 408 logger.warn('Going to resend topUpReport because status code is not 200 (' + topUpReportError.res.statusCode + ')', {req: debugInfo});
408 return true; 409 return true;
409 } 410 }
410 } 411 }
411 } catch(e) {} 412 } catch(e) {}
412 413
413 try { 414 try {
414 if (topUpReportError.toString().indexOf('Invalid XML-RPC message') < 0) { 415 if (topUpReportError.toString().indexOf('Invalid XML-RPC message') < 0) {
415 logger.verbose('errorOnTopUpReport', {error: topUpReportError.toString()}); 416 logger.verbose('errorOnTopUpReport', {error: topUpReportError.toString()});
416 return true; 417 return true;
417 } 418 }
418 } 419 }
419 catch(e) {} 420 catch(e) {}
420 421
421 return false; 422 return false;
422 423
423 } 424 }
424 425
425 function sendTopUpReport(reverseUrls, params, urlIdx, retry) { 426 function sendTopUpReport(reverseUrls, params, urlIdx, retry) {
426 if (retry === null || retry === undefined) { 427 if (retry === null || retry === undefined) {
427 retry = maxTopUpReportRetry; 428 retry = maxTopUpReportRetry;
428 } 429 }
429 430
430 if (urlIdx === null || urlIdx === undefined) { 431 if (urlIdx === null || urlIdx === undefined) {
431 urlIdx = 0; 432 urlIdx = 0;
432 } 433 }
433 434
434 if (urlIdx >= reverseUrls.length) { 435 if (urlIdx >= reverseUrls.length) {
435 logger.warn('No other reverse urls for partner available', {reverseUrls: reverseUrls, params: params}); 436 logger.warn('No other reverse urls for partner available', {reverseUrls: reverseUrls, params: params});
436 437
437 if (retry > 0) { 438 if (retry > 0) {
438 logger.warn('Retrying to send topUpReport to partner first url', {remaining_retry: retry-1, reverseUrls: reverseUrls, params: params}); 439 logger.warn('Retrying to send topUpReport to partner first url', {remaining_retry: retry-1, reverseUrls: reverseUrls, params: params});
439 setTimeout( 440 setTimeout(
440 sendTopUpReport, 441 sendTopUpReport,
441 delayBeforeRetryTopUpReport, 442 delayBeforeRetryTopUpReport,
442 reverseUrls, 443 reverseUrls,
443 params, 444 params,
444 0, 445 0,
445 --retry 446 --retry
446 ) 447 )
447 return; 448 return;
448 } 449 }
449 450
450 logger.warn('topUpReport retry exceed', {reverseUrls: reverseUrls, params: params}); 451 logger.warn('topUpReport retry exceed', {reverseUrls: reverseUrls, params: params});
451 return; 452 return;
452 } 453 }
453 454
454 var partnerUrl = url.parse(reverseUrls[urlIdx]); 455 var partnerUrl = url.parse(reverseUrls[urlIdx]);
455 456
456 var clientOptions = { 457 var clientOptions = {
457 host: partnerUrl.hostname 458 host: partnerUrl.hostname
458 , port: partnerUrl.port 459 , port: partnerUrl.port
459 , path: partnerUrl.pathname 460 , path: partnerUrl.pathname
460 }; 461 };
461 462
462 //logger.verbose('Preparing to send topUpReport', {clientOptions: clientOptions}); 463 //logger.verbose('Preparing to send topUpReport', {clientOptions: clientOptions});
463 464
464 var client; 465 var client;
465 if (partnerUrl.protocol == 'https:') { 466 if (partnerUrl.protocol == 'https:') {
466 client = xmlrpc.createSecureClient(clientOptions); 467 client = xmlrpc.createSecureClient(clientOptions);
467 } else { 468 } else {
468 client = xmlrpc.createClient(clientOptions); 469 client = xmlrpc.createClient(clientOptions);
469 } 470 }
470 471
471 var methodName = 'topUpReport'; 472 var methodName = 'topUpReport';
472 logger.info('Requesting topUpReport', {protocol: partnerUrl.protocol, clientOptions: clientOptions, params: params}); 473 logger.info('Requesting topUpReport', {protocol: partnerUrl.protocol, clientOptions: clientOptions, params: params});
473 474
474 client.methodCall(methodName, [ params ], function (topUpReportError, value) { 475 client.methodCall(methodName, [ params ], function (topUpReportError, value) {
475 476
476 if (errorOnTopUpReport(topUpReportError, {params: params, clientOptions: clientOptions})) { 477 if (errorOnTopUpReport(topUpReportError, {params: params, clientOptions: clientOptions})) {
477 478
478 logger.warn('Error sending topUpReport retrying another url (if available): ' + topUpReportError, 479 logger.warn('Error sending topUpReport retrying another url (if available): ' + topUpReportError,
479 { 480 {
480 error: topUpReportError.toString(), 481 error: topUpReportError.toString(),
481 responseBody: topUpReportError.body, 482 responseBody: topUpReportError.body,
482 params: params, 483 params: params,
483 clientOptions: clientOptions, 484 clientOptions: clientOptions,
484 } 485 }
485 ); 486 );
486 sendTopUpReport(reverseUrls, params, ++urlIdx, retry); 487 sendTopUpReport(reverseUrls, params, ++urlIdx, retry);
487 return; 488 return;
488 489
489 } 490 }
490 491
491 logger.verbose("topUpReport ACK", {params: params, clientOptions: clientOptions}); 492 logger.verbose("topUpReport ACK", {params: params, clientOptions: clientOptions});
492 493
493 }); 494 });
494 } 495 }
495 496
496 function createResponseServer() { 497 function createResponseServer() {
497 var httpServer = http.createServer(function(req, res) { 498 var httpServer = http.createServer(function(req, res) {
498 499
499 res.end(); 500 res.end();
500 501
501 var parsed_url = url.parse(req.url, true, true); 502 var parsed_url = url.parse(req.url, true, true);
502 logger.info("Hit on response server", {qs: parsed_url.query}); 503 logger.info("Hit on response server", {qs: parsed_url.query});
503 504
504 sendReply(parsed_url.query); 505 sendReply(parsed_url.query);
505 506
506 }); 507 });
507 508
508 httpServer.listen(config.res_port, function() { 509 httpServer.listen(config.res_port, function() {
509 logger.info('HTTP Response server listen on port ' + config.res_port); 510 logger.info('HTTP Response server listen on port ' + config.res_port);
510 }); 511 });
511 } 512 }
512 513
513 exports.start = start; 514 exports.start = start;
514 515