Commit bc3c8ee446f8349951f7313165e29dd82c8fd8ae

Authored by Adhidarma Hadiwinoto
1 parent ad2d5e4d92
Exists in master

require moment

Showing 2 changed files with 2 additions and 0 deletions Inline Diff

1 "use strict"; 1 "use strict";
2 2
3 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; 3 process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
4 4
5 const fs = require('fs'); 5 const fs = require('fs');
6 const url = require('url'); 6 const url = require('url');
7 const https = require('https'); 7 const https = require('https');
8 const xmlrpc = require('xmlrpc'); 8 const xmlrpc = require('xmlrpc');
9 const moment = require('moment');
9 10
10 const config = require('komodo-sdk/config'); 11 const config = require('komodo-sdk/config');
11 const logger = require('komodo-sdk/logger'); 12 const logger = require('komodo-sdk/logger');
12 const matrix = require('komodo-sdk/matrix'); 13 const matrix = require('komodo-sdk/matrix');
13 const pull = require('komodo-sdk/gateway/pull'); 14 const pull = require('komodo-sdk/gateway/pull');
14 15
15 const st24 = require('./st24'); 16 const st24 = require('./st24');
16 17
17 const partnerRc = fs.existsSync(__dirname + '/../rc-local.json') ? require('../rc-local.json') : require('./partner-rc.json'); 18 const partnerRc = fs.existsSync(__dirname + '/../rc-local.json') ? require('../rc-local.json') : require('./partner-rc.json');
18 19
19 if (config.partner.use_sslv3) { 20 if (config.partner.use_sslv3) {
20 https.globalAgent.options.secureProtocol = 'SSLv3_method'; 21 https.globalAgent.options.secureProtocol = 'SSLv3_method';
21 } 22 }
22 23
23 function createXmlRpcClient(endpoint) { 24 function createXmlRpcClient(endpoint) {
24 const partnerUrl = url.parse(endpoint); 25 const partnerUrl = url.parse(endpoint);
25 const clientOptions = { 26 const clientOptions = {
26 host: partnerUrl.hostname, 27 host: partnerUrl.hostname,
27 port: partnerUrl.port, 28 port: partnerUrl.port,
28 path: partnerUrl.pathname 29 path: partnerUrl.pathname
29 }; 30 };
30 31
31 logger.verbose('Creating XML-RPC client using ' + partnerUrl.protocol, clientOptions); 32 logger.verbose('Creating XML-RPC client using ' + partnerUrl.protocol, clientOptions);
32 33
33 return (partnerUrl.protocol === 'https:') ? xmlrpc.createSecureClient(clientOptions) : xmlrpc.createClient(clientOptions); 34 return (partnerUrl.protocol === 'https:') ? xmlrpc.createSecureClient(clientOptions) : xmlrpc.createClient(clientOptions);
34 } 35 }
35 36
36 function buy(task) { 37 function buy(task) {
37 _topUpRequest(task); 38 _topUpRequest(task);
38 } 39 }
39 40
40 function _topUpRequest(task, isAdvice) { 41 function _topUpRequest(task, isAdvice) {
41 const params = { 42 const params = {
42 MSISDN: config.partner.msisdn || config.partner.userid, 43 MSISDN: config.partner.msisdn || config.partner.userid,
43 REQUESTID: task.trx_id, 44 REQUESTID: task.trx_id,
44 PIN: config.partner.pin || config.partner.password, 45 PIN: config.partner.pin || config.partner.password,
45 NOHP: task.destination, 46 NOHP: task.destination,
46 NOM: task.remote_product 47 NOM: task.remote_product
47 }; 48 };
48 49
49 const xmlrpcMethod = 'topUpRequest'; 50 const xmlrpcMethod = 'topUpRequest';
50 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url}); 51 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url});
51 52
52 const client = createXmlRpcClient(config.partner.url); 53 const client = createXmlRpcClient(config.partner.url);
53 client.methodCall(xmlrpcMethod, [ params ], function (err, value) { 54 client.methodCall(xmlrpcMethod, [ params ], function (err, value) {
54 55
55 if (err) { 56 if (err) {
56 57
57 let msg = 'XMLRPC Client Error: ' + err; 58 let msg = 'XMLRPC Client Error: ' + err;
58 let rc = '68'; 59 let rc = '68';
59 60
60 if ( 61 if (
61 !isAdvice && 62 !isAdvice &&
62 ( 63 (
63 err.code === 'ECONNREFUSED' 64 err.code === 'ECONNREFUSED'
64 || err.code === 'EHOSTUNREACH' 65 || err.code === 'EHOSTUNREACH'
65 || (err.code === 'ETIMEDOUT' && err.syscall === "connect") 66 || (err.code === 'ETIMEDOUT' && err.syscall === "connect")
66 || (err.code === 'EPROTO' && err.syscall === "write") 67 || (err.code === 'EPROTO' && err.syscall === "write")
67 ) 68 )
68 ) { 69 ) {
69 rc = '91'; 70 rc = '91';
70 } 71 }
71 72
72 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err}); 73 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err});
73 report({ 74 report({
74 trx_id: task.trx_id, 75 trx_id: task.trx_id,
75 rc: rc, 76 rc: rc,
76 message: 'INTERNAL: ' + msg, 77 message: 'INTERNAL: ' + msg,
77 misc: { 78 misc: {
78 task: task 79 task: task
79 } 80 }
80 }); 81 });
81 82
82 if (rc === '68') { 83 if (rc === '68') {
83 setTimeout( 84 setTimeout(
84 function() { advice(task); }, 85 function() { advice(task); },
85 5 * 60 * 1000 86 5 * 60 * 1000
86 ); 87 );
87 } 88 }
88 89
89 return; 90 return;
90 } 91 }
91 92
92 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value}); 93 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value});
93 matrix.last_topupRequest_ack = value; 94 matrix.last_topupRequest_ack = value;
94 95
95 report({ 96 report({
96 trx_id: task.trx_id, 97 trx_id: task.trx_id,
97 rc: partnerRc[value.RESPONSECODE] || '40', 98 rc: partnerRc[value.RESPONSECODE] || '40',
98 message: value.MESSAGE, 99 message: value.MESSAGE,
99 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE), 100 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE),
100 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE), 101 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE),
101 raw: value, 102 raw: value,
102 misc: { 103 misc: {
103 task: task 104 task: task
104 } 105 }
105 }); 106 });
106 }); 107 });
107 } 108 }
108 109
109 function _topUpInquiry(task) { 110 function _topUpInquiry(task) {
110 const params = { 111 const params = {
111 REQUESTID: task.trx_id, 112 REQUESTID: task.trx_id,
112 MSISDN: config.partner.msisdn || config.partner.userid, 113 MSISDN: config.partner.msisdn || config.partner.userid,
113 PIN: config.partner.pin || config.partner.password, 114 PIN: config.partner.pin || config.partner.password,
114 NOHP: task.destination 115 NOHP: task.destination
115 }; 116 };
116 117
117 const xmlrpcMethod = 'topUpInquiry'; 118 const xmlrpcMethod = 'topUpInquiry';
118 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url}); 119 logger.info('Preparing XMLRPC request', {method: xmlrpcMethod, params: params, partnerUrl: config.partner.url});
119 120
120 const client = createXmlRpcClient(config.partner.url); 121 const client = createXmlRpcClient(config.partner.url);
121 client.methodCall(xmlrpcMethod, [ params ], function (err, value) { 122 client.methodCall(xmlrpcMethod, [ params ], function (err, value) {
122 123
123 if (err) { 124 if (err) {
124 125
125 const msg = 'XMLRPC Client Error: ' + err; 126 const msg = 'XMLRPC Client Error: ' + err;
126 127
127 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err}); 128 logger.warn(msg, {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, err: err});
128 report({ 129 report({
129 trx_id: task.trx_id, 130 trx_id: task.trx_id,
130 rc: '68', 131 rc: '68',
131 message: 'INTERNAL: ' + msg, 132 message: 'INTERNAL: ' + msg,
132 misc: { 133 misc: {
133 task: task 134 task: task
134 } 135 }
135 }); 136 });
136 137
137 return; 138 return;
138 } 139 }
139 140
140 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value}); 141 logger.info('Got XMLRPC response from partner for', {method: xmlrpcMethod, trx_id: task.trx_id, destination: task.destination, response: value});
141 //matrix.last_topupRequest_ack = value; 142 //matrix.last_topupRequest_ack = value;
142 143
143 report({ 144 report({
144 trx_id: task.trx_id, 145 trx_id: task.trx_id,
145 rc: partnerRc[value.RESPONSECODE] || '40', 146 rc: partnerRc[value.RESPONSECODE] || '40',
146 message: value.MESSAGE, 147 message: value.MESSAGE,
147 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE, config.sn_pattern), 148 sn: (value.SN || '').replace(/;$/, '') || st24.extractSnFromMessage(value.MESSAGE, config.sn_pattern),
148 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE), 149 amount: value.PRICE || st24.extractPriceFromMsg(value.MESSAGE),
149 raw: value, 150 raw: value,
150 misc: { 151 misc: {
151 task: task 152 task: task
152 } 153 }
153 }); 154 });
154 }); 155 });
155 } 156 }
156 157
157 function advice(task) { 158 function advice(task) {
158 if (config && config.advice_is_not_allowed) { 159 if (config && config.advice_is_not_allowed) {
159 return; 160 return;
160 } 161 }
161 162
162 if (config && config.advice_max_age_ms) { 163 if (config && config.advice_max_age_ms) {
163 if (moment() - moment(task.created) > config.advice_max_age_ms) { 164 if (moment() - moment(task.created) > config.advice_max_age_ms) {
164 logger.verbose('Ignoring advice request because of expired task', {trx_id: task.trx_id, destination: task.destination, product: task.product, created: task.created, max_age: config.advice_max_age_ms}); 165 logger.verbose('Ignoring advice request because of expired task', {trx_id: task.trx_id, destination: task.destination, product: task.product, created: task.created, max_age: config.advice_max_age_ms});
165 return; 166 return;
166 } 167 }
167 } 168 }
168 169
169 if (config && config.advice_is_topuprequest) { 170 if (config && config.advice_is_topuprequest) {
170 _topUpRequest(task, true); 171 _topUpRequest(task, true);
171 } 172 }
172 else { 173 else {
173 _topUpInquiry(task); 174 _topUpInquiry(task);
174 } 175 }
175 } 176 }
176 177
177 function report(data) { 178 function report(data) {
178 if (!data) { 179 if (!data) {
179 return; 180 return;
180 } 181 }
181 182
182 matrix.last_report_to_core = data; 183 matrix.last_report_to_core = data;
183 pull.report(data); 184 pull.report(data);
184 } 185 }
185 186
186 exports.buy = buy; 187 exports.buy = buy;
187 exports.advice = advice; 188 exports.advice = advice;
188 exports.report = report; 189 exports.report = report;
189 190
1 { 1 {
2 "name": "komodo-gw-st24", 2 "name": "komodo-gw-st24",
3 "version": "1.2.1", 3 "version": "1.2.1",
4 "description": "Komodo Gateway to ST24 XML-RPC", 4 "description": "Komodo Gateway to ST24 XML-RPC",
5 "main": "index.js", 5 "main": "index.js",
6 "scripts": { 6 "scripts": {
7 "test": "mocha", 7 "test": "mocha",
8 "postversion": "git push && git push --tags" 8 "postversion": "git push && git push --tags"
9 }, 9 },
10 "repository": { 10 "repository": {
11 "type": "git", 11 "type": "git",
12 "url": "git@gitlab.kodesumber.com:komodo/komodo-gw-st24.git" 12 "url": "git@gitlab.kodesumber.com:komodo/komodo-gw-st24.git"
13 }, 13 },
14 "keywords": [ 14 "keywords": [
15 "komodo", 15 "komodo",
16 "tektrans", 16 "tektrans",
17 "ppob", 17 "ppob",
18 "st24", 18 "st24",
19 "xmlrpc", 19 "xmlrpc",
20 "xml-rpc" 20 "xml-rpc"
21 ], 21 ],
22 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>", 22 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>",
23 "license": "ISC", 23 "license": "ISC",
24 "dependencies": { 24 "dependencies": {
25 "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git", 25 "komodo-sdk": "git+http://gitlab.kodesumber.com/komodo/komodo-sdk.git",
26 "moment": "^2.22.1",
26 "xmlrpc": "^1.3.2" 27 "xmlrpc": "^1.3.2"
27 }, 28 },
28 "devDependencies": { 29 "devDependencies": {
29 "should": "^13.2.1" 30 "should": "^13.2.1"
30 } 31 }
31 } 32 }
32 33