Commit e2bf68a794824e9c10c4c231facc8433500eb1a6

Authored by Adhidarma Hadiwinoto
1 parent 0b9b60b118
Exists in master

log xmlbody

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