Compare View

switch
from
...
to
 
Commits (2)

Changes

Showing 2 changed files Inline Diff

1 "use strict"; 1 "use strict";
2 2
3 const request = require('request'); 3 const request = require('request');
4 4
5 const config = require('../config'); 5 const config = require('../config');
6 const logger = require('../logger'); 6 const logger = require('../logger');
7 const matrix = require('../matrix'); 7 const matrix = require('../matrix');
8 const controlPanel = require('../control-panel'); 8 const controlPanel = require('../control-panel');
9 const heartbeat = require('../heartbeat'); 9 const heartbeat = require('../heartbeat');
10 const core_url = require('../core-url'); 10 const core_url = require('../core-url');
11 11
12 const taskArchive = require('./task-archive'); 12 const taskArchive = require('./task-archive');
13 13
14 const MAX_SLEEP_BEFORE_RESEND_MS = 500; 14 const MAX_SLEEP_BEFORE_RESEND_MS = 500;
15 const DELAY_AFTER_NO_TASK_MS = 500; 15 const DELAY_AFTER_NO_TASK_MS = 500;
16 16
17 let is_on_delay_after_no_task = false; 17 let is_on_delay_after_no_task = false;
18 18
19 if (config.handler_name) { 19 if (config.handler_name) {
20 process.title = "KOMODO-GW@" + config.handler_name; 20 process.title = "KOMODO-GW@" + config.handler_name;
21 } 21 }
22 22
23 matrix.sdk_pending_tasks_count = 0; 23 matrix.sdk_pending_tasks_count = 0;
24 matrix.sdk_unresponsed_tasks_count = 0; 24 matrix.sdk_unresponsed_tasks_count = 0;
25 matrix.sdk_pending_with_response_tasks_count = 0; 25 matrix.sdk_pending_with_response_tasks_count = 0;
26 26
27 if (!matrix.sdk_pending_tasks) { 27 if (!matrix.sdk_pending_tasks) {
28 matrix.sdk_pending_tasks = []; 28 matrix.sdk_pending_tasks = [];
29 } 29 }
30 30
31 if (!matrix.sdk_unresponsed_tasks) { 31 if (!matrix.sdk_unresponsed_tasks) {
32 matrix.sdk_unresponsed_tasks = []; 32 matrix.sdk_unresponsed_tasks = [];
33 } 33 }
34 34
35 if (!matrix.sdk_pending_with_response_tasks) { 35 if (!matrix.sdk_pending_with_response_tasks) {
36 matrix.sdk_pending_with_response_tasks = []; 36 matrix.sdk_pending_with_response_tasks = [];
37 } 37 }
38 38
39 heartbeat.setModuleType('gateway'); 39 heartbeat.setModuleType('gateway');
40 40
41 var partner; 41 var partner;
42 42
43 function onNoTask() { 43 function onNoTask() {
44 is_on_delay_after_no_task = true; 44 is_on_delay_after_no_task = true;
45 setTimeout(function() { 45 setTimeout(function() {
46 is_on_delay_after_no_task = false; 46 is_on_delay_after_no_task = false;
47 }, DELAY_AFTER_NO_TASK_MS) 47 }, DELAY_AFTER_NO_TASK_MS)
48 } 48 }
49 49
50 function setPartner(_partner) { 50 function setPartner(_partner) {
51 partner = _partner; 51 partner = _partner;
52 } 52 }
53 53
54 function pullTask() { 54 function pullTask() {
55 if (is_on_delay_after_no_task) { 55 if (is_on_delay_after_no_task) {
56 return; 56 return;
57 } 57 }
58 58
59 if (!partner) { 59 if (!partner) {
60 return; 60 return;
61 } 61 }
62 62
63 let core_pull_task_url; 63 let core_pull_task_url;
64 64
65 if (core_url) { 65 if (core_url) {
66 core_pull_task_url = core_url + '/pull/task'; 66 core_pull_task_url = core_url + '/pull/task';
67 } 67 }
68 else if (config && config.pull_url && config.pull_url.task) { 68 else if (config && config.pull_url && config.pull_url.task) {
69 core_pull_task_url = config.pull_url.task.replace('<CORE_APIKEY>', config.core_apikey); 69 core_pull_task_url = config.pull_url.task.replace('<CORE_APIKEY>', config.core_apikey);
70 } 70 }
71 71
72 if (!core_pull_task_url) { 72 if (!core_pull_task_url) {
73 logger.warn('Unknown CORE task url'); 73 logger.warn('Unknown CORE task url');
74 return; 74 return;
75 } 75 }
76 76
77 let options = { 77 let options = {
78 url: core_pull_task_url, 78 url: core_pull_task_url,
79 qs: { 79 qs: {
80 handler: config.handler_name, 80 handler: config.handler_name,
81 products: config.products.join(','), 81 products: config.products.join(','),
82 advice_url: (config && config.push_server && config.push_server.apikey && config.push_server.advice && config.push_server.advice.url && config.push_server.advice.port) ? config.push_server.advice.url : null 82 advice_url: (config && config.push_server && config.push_server.apikey && config.push_server.advice && config.push_server.advice.url && config.push_server.advice.port) ? config.push_server.advice.url : null
83 } 83 }
84 } 84 }
85 85
86 if (config && config.debug_request_task_to_core) { 86 if (config && config.debug_request_task_to_core) {
87 logger.verbose('Requesting task to CORE', {url: options.url, qs: options.qs}); 87 logger.verbose('Requesting task to CORE', {url: options.url, qs: options.qs});
88 } 88 }
89 89
90 request(options, function(error, response, body) { 90 request(options, function(error, response, body) {
91 if (error) { 91 if (error) {
92 if (matrix.core_is_healthy) { 92 if (matrix.core_is_healthy) {
93 logger.warn('Error pulling task from CORE', {error: error}); 93 logger.warn('Error pulling task from CORE', {error: error});
94 } 94 }
95 matrix.core_is_healthy = false; 95 matrix.core_is_healthy = false;
96 onNoTask(); 96 onNoTask();
97 return; 97 return;
98 } 98 }
99 99
100 if (response.statusCode != 200) { 100 if (response.statusCode != 200) {
101 if (matrix.core_is_healthy) { 101 if (matrix.core_is_healthy) {
102 logger.warn('CORE http response status code for pull task is not 200', {http_response_status: response.statusCode}); 102 logger.warn('CORE http response status code for pull task is not 200', {http_response_status: response.statusCode});
103 } 103 }
104 matrix.core_is_healthy = false; 104 matrix.core_is_healthy = false;
105 onNoTask(); 105 onNoTask();
106 return; 106 return;
107 } 107 }
108 108
109 if (!matrix.core_is_healthy) { 109 if (!matrix.core_is_healthy) {
110 logger.verbose('CORE is healthy'); 110 logger.verbose('CORE is healthy');
111 } 111 }
112 matrix.core_is_healthy = true; 112 matrix.core_is_healthy = true;
113 113
114 if (body == 'NONE') { 114 if (body == 'NONE') {
115 onNoTask(); 115 onNoTask();
116 return; 116 return;
117 } 117 }
118 118
119 forwardCoreTaskToPartner(body); 119 forwardCoreTaskToPartner(body);
120 }); 120 });
121 } 121 }
122 122
123 function putTaskToMatrix(task) { 123 function putTaskToMatrix(task) {
124 if (matrix.sdk_unresponsed_tasks.indexOf(task.trx_id) < 0) { 124 if (matrix.sdk_unresponsed_tasks.indexOf(task.trx_id) < 0) {
125 matrix.sdk_unresponsed_tasks.push(task.trx_id); 125 matrix.sdk_unresponsed_tasks.push(task.trx_id);
126 matrix.sdk_unresponsed_tasks_count = matrix.sdk_unresponsed_tasks.length; 126 matrix.sdk_unresponsed_tasks_count = matrix.sdk_unresponsed_tasks.length;
127 } 127 }
128 128
129 if (matrix.sdk_pending_tasks.indexOf(task.trx_id) < 0) { 129 if (matrix.sdk_pending_tasks.indexOf(task.trx_id) < 0) {
130 matrix.sdk_pending_tasks.push(task.trx_id); 130 matrix.sdk_pending_tasks.push(task.trx_id);
131 matrix.sdk_pending_tasks_count = matrix.sdk_pending_tasks.length; 131 matrix.sdk_pending_tasks_count = matrix.sdk_pending_tasks.length;
132 } 132 }
133 } 133 }
134 134
135 function updateTaskOnMatrix(trx_id, rc) { 135 function updateTaskOnMatrix(trx_id, rc) {
136 const unresponsed_task_idx = matrix.sdk_unresponsed_tasks.indexOf(trx_id); 136 const unresponsed_task_idx = matrix.sdk_unresponsed_tasks.indexOf(trx_id);
137 if (unresponsed_task_idx >= 0) { 137 if (unresponsed_task_idx >= 0) {
138 matrix.sdk_unresponsed_tasks.splice(unresponsed_task_idx, 1); 138 matrix.sdk_unresponsed_tasks.splice(unresponsed_task_idx, 1);
139 } 139 }
140 matrix.sdk_unresponsed_tasks_count = matrix.sdk_unresponsed_tasks.length; 140 matrix.sdk_unresponsed_tasks_count = matrix.sdk_unresponsed_tasks.length;
141 141
142 if (rc == '68') { 142 if (rc == '68') {
143 const pending_with_response_tasks_idx = matrix.sdk_pending_with_response_tasks.indexOf(trx_id); 143 const pending_with_response_tasks_idx = matrix.sdk_pending_with_response_tasks.indexOf(trx_id);
144 if (pending_with_response_tasks_idx < 0) { 144 if (pending_with_response_tasks_idx < 0) {
145 matrix.sdk_pending_with_response_tasks.push(trx_id); 145 matrix.sdk_pending_with_response_tasks.push(trx_id);
146 matrix.sdk_pending_with_response_tasks_count = matrix.sdk_pending_with_response_tasks.length; 146 matrix.sdk_pending_with_response_tasks_count = matrix.sdk_pending_with_response_tasks.length;
147 } 147 }
148 } 148 }
149 else { 149 else {
150 const pending_task_idx = matrix.sdk_pending_tasks.indexOf(trx_id); 150 const pending_task_idx = matrix.sdk_pending_tasks.indexOf(trx_id);
151 if (pending_task_idx >= 0) { 151 if (pending_task_idx >= 0) {
152 matrix.sdk_pending_tasks.splice(pending_task_idx, 1); 152 matrix.sdk_pending_tasks.splice(pending_task_idx, 1);
153 matrix.sdk_pending_tasks_count = matrix.sdk_pending_tasks.length; 153 matrix.sdk_pending_tasks_count = matrix.sdk_pending_tasks.length;
154 } 154 }
155 155
156 const pending_with_response_tasks_idx = matrix.sdk_pending_with_response_tasks.indexOf(trx_id); 156 const pending_with_response_tasks_idx = matrix.sdk_pending_with_response_tasks.indexOf(trx_id);
157 if (pending_with_response_tasks_idx >= 0) { 157 if (pending_with_response_tasks_idx >= 0) {
158 matrix.sdk_pending_with_response_tasks.splice(pending_with_response_tasks_idx, 1); 158 matrix.sdk_pending_with_response_tasks.splice(pending_with_response_tasks_idx, 1);
159 matrix.sdk_pending_with_response_tasks_count = matrix.sdk_pending_with_response_tasks.length; 159 matrix.sdk_pending_with_response_tasks_count = matrix.sdk_pending_with_response_tasks.length;
160 } 160 }
161 } 161 }
162 } 162 }
163 163
164 function forwardCoreTaskToPartner(coreMessage) { 164 function forwardCoreTaskToPartner(coreMessage) {
165 let task; 165 let task;
166 166
167 try { 167 try {
168 task = JSON.parse(coreMessage); 168 task = JSON.parse(coreMessage);
169 } 169 }
170 catch(e) { 170 catch(e) {
171 logger.warn('Exception on parsing CORE pull task response', {coreMessage: coreMessage, error: e}); 171 logger.warn('Exception on parsing CORE pull task response', {coreMessage: coreMessage, error: e});
172 } 172 }
173 173
174 incrementCounterTrx(); 174 incrementCounterTrx();
175 175
176 task.remote_product = getRemoteProduct(task.product); 176 task.remote_product = getRemoteProduct(task.product);
177 177
178 putTaskToMatrix(task); 178 putTaskToMatrix(task);
179 179
180 taskArchive.get(task, function(res) { 180 taskArchive.get(task, function(res) {
181 if (res && partner.advice) { 181 if (res && partner.advice) {
182 partner.advice(task); 182 partner.advice(task);
183 } 183 }
184 else { 184 else {
185 partner.buy(task); 185 partner.buy(task);
186 } 186 }
187 }); 187 });
188 } 188 }
189 189
190 function replaceRc(original_rc) { 190 function replaceRc(original_rc) {
191 if (!config || !config.replace_rc) { 191 if (!config || !config.replace_rc) {
192 return original_rc; 192 return original_rc;
193 } 193 }
194 194
195 return config.replace_rc[original_rc] || original_rc; 195 return config.replace_rc[original_rc] || original_rc;
196 } 196 }
197 197
198 function report(data) { 198 function report(data) {
199 199
200 let core_pull_report_url; 200 let core_pull_report_url;
201 201
202 if (data && data.trx_id && data.rc) { 202 if (data && data.trx_id && data.rc) {
203 updateTaskOnMatrix(data.trx_id, data.rc); 203 updateTaskOnMatrix(data.trx_id, data.rc);
204 } 204 }
205 205
206 if (core_url) { 206 if (core_url) {
207 core_pull_report_url = core_url + '/pull/report'; 207 core_pull_report_url = core_url + '/pull/report';
208 } else if (config && config.pull_url && config.pull_url.report) { 208 } else if (config && config.pull_url && config.pull_url.report) {
209 core_pull_report_url = config.pull_url.report.replace('<CORE_APIKEY>', config.core_apikey); 209 core_pull_report_url = config.pull_url.report.replace('<CORE_APIKEY>', config.core_apikey);
210 } 210 }
211 211
212 if (!core_pull_report_url) { 212 if (!core_pull_report_url) {
213 logger.warn('Unknown CORE report url'); 213 logger.warn('Unknown CORE report url');
214 return; 214 return;
215 } 215 }
216 216
217 if (config && config.push_server && config.push_server.apikey && config.push_server.advice && config.push_server.advice.url && config.push_server.advice.port) { 217 if (config && config.push_server && config.push_server.apikey && config.push_server.advice && config.push_server.advice.url && config.push_server.advice.port) {
218 if (!data.misc) { 218 if (!data.misc) {
219 data.misc = {}; 219 data.misc = {};
220 } 220 }
221 221
222 //logger.verbose('Including advice url on report'); 222 //logger.verbose('Including advice url on report');
223 data.misc.advice_url = config.push_server.advice.url;
224 } 223 data.misc.advice_url = config.push_server.advice.url;
225 224 }
226 let options = { 225
227 url: core_pull_report_url, 226 let options = {
228 form: { 227 url: core_pull_report_url,
229 trx_id: data.trx_id, 228 form: {
230 rc: replaceRc(data.rc), 229 trx_id: data.trx_id,
231 rc_from_handler: data.rc_from_handler, 230 rc: replaceRc(data.rc),
231 rc_from_handler: data.rc_from_handler,
232 message: data.message, 232 message: data.message,
233 handler: config.handler_name, 233 handler: config.handler_name,
234 sn: data.sn, 234 sn: data.sn,
235 amount: data.amount, 235 amount: data.amount,
236 raw: data.raw, 236 raw: data.raw,
237 misc: data.misc 237 misc: data.misc
238 } 238 }
239 } 239 }
240 240
241 if (!config.do_not_verbose_log_report) { 241 if (!config.do_not_verbose_log_report) {
242 logger.verbose('Report to CORE using HTTP POST'); 242 logger.verbose('Report to CORE using HTTP POST');
243 } 243 }
244 244
245 request.post(options, function(error, response, body) { 245 request.post(options, function(error, response, body) {
246 if (error) { 246 if (error) {
247 logger.warn('Error reporting to CORE', {error: error}); 247 logger.warn('Error reporting to CORE', {error: error});
248 resendReport(data); 248 resendReport(data);
249 } 249 }
250 else if (response.statusCode != 200) { 250 else if (response.statusCode != 200) {
251 logger.warn('Error reporting to CORE, http response status is not 200', {requestOptions: options, http_response_status: response.statusCode}); 251 logger.warn('Error reporting to CORE, http response status is not 200', {requestOptions: options, http_response_status: response.statusCode});
252 resendReport(data); 252 resendReport(data);
253 } 253 }
254 else if (!config.do_not_verbose_log_report) { 254 else if (!config.do_not_verbose_log_report) {
255 logger.verbose('Report has been sent to CORE', {requestOptions: options}); 255 logger.verbose('Report has been sent to CORE', {requestOptions: options});
256 } 256 }
257 }); 257 });
258 } 258 }
259 259
260 function resendReport(data) { 260 function resendReport(data) {
261 const sleepBeforeResend = Math.round(Math.random() * MAX_SLEEP_BEFORE_RESEND_MS) 261 const sleepBeforeResend = Math.round(Math.random() * MAX_SLEEP_BEFORE_RESEND_MS)
262 logger.verbose('Resend report to CORE in ' + sleepBeforeResend + 'ms') 262 logger.verbose('Resend report to CORE in ' + sleepBeforeResend + 'ms')
263 263
264 setTimeout( 264 setTimeout(
265 function() { 265 function() {
266 report(data); 266 report(data);
267 }, 267 },
268 sleepBeforeResend 268 sleepBeforeResend
269 ) 269 )
270 } 270 }
271 271
272 function isPaused() { 272 function isPaused() {
273 return matrix.paused; 273 return matrix.paused;
274 } 274 }
275 275
276 function pause() { 276 function pause() {
277 matrix.paused = true; 277 matrix.paused = true;
278 } 278 }
279 279
280 function resume() { 280 function resume() {
281 matrix.pause = false; 281 matrix.pause = false;
282 } 282 }
283 283
284 function initMatrix() { 284 function initMatrix() {
285 if (!matrix) { 285 if (!matrix) {
286 matrix = {}; 286 matrix = {};
287 } 287 }
288 288
289 matrix.counter = { 289 matrix.counter = {
290 trx: 0 290 trx: 0
291 } 291 }
292 } 292 }
293 293
294 function incrementCounterTrx() { 294 function incrementCounterTrx() {
295 matrix.counter.trx++; 295 matrix.counter.trx++;
296 } 296 }
297 297
298 function getRemoteProduct(product) { 298 function getRemoteProduct(product) {
299 let remoteProduct = config.remote_products[product]; 299 let remoteProduct = config.remote_products[product];
300 return remoteProduct || product; 300 return remoteProduct || product;
301 } 301 }
302 302
303 initMatrix(); 303 initMatrix();
304 setInterval(pullTask, config.pull_interval_ms || 1000); 304 setInterval(pullTask, config.pull_interval_ms || 1000);
305 305
306 exports.setPartner = setPartner; 306 exports.setPartner = setPartner;
307 exports.isPaused = isPaused; 307 exports.isPaused = isPaused;
308 exports.pause = pause; 308 exports.pause = pause;
309 exports.resume = resume; 309 exports.resume = resume;
310 exports.report = report; 310 exports.report = report;
311 exports.getRemoteProduct = getRemoteProduct; 311 exports.getRemoteProduct = getRemoteProduct;
1 { 1 {
2 "name": "komodo-sdk", 2 "name": "komodo-sdk",
3 "version": "1.26.8", 3 "version": "1.27.0",
4 "description": "SDK for Komodo", 4 "description": "SDK for Komodo",
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-sdk.git" 12 "url": "git@gitlab.kodesumber.com:komodo/komodo-sdk.git"
13 }, 13 },
14 "keywords": [ 14 "keywords": [
15 "ppob", 15 "ppob",
16 "payment", 16 "payment",
17 "komodo" 17 "komodo"
18 ], 18 ],
19 "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>", 19 "author": "Adhidarma Hadiwinoto <gua@adhisimon.org>",
20 "license": "ISC", 20 "license": "ISC",
21 "dependencies": { 21 "dependencies": {
22 "basic-auth": "^2.0.0", 22 "basic-auth": "^2.0.0",
23 "body-parser": "^1.18.2", 23 "body-parser": "^1.18.2",
24 "dot-object": "^1.7.0", 24 "dot-object": "^1.7.0",
25 "express": "^4.16.3", 25 "express": "^4.16.3",
26 "express-session": "^1.15.6", 26 "express-session": "^1.15.6",
27 "json-query": "^2.2.2", 27 "json-query": "^2.2.2",
28 "lru-cache": "^4.1.1", 28 "lru-cache": "^4.1.1",
29 "macaddress": "^0.2.8", 29 "macaddress": "^0.2.8",
30 "moment": "^2.19.1", 30 "moment": "^2.19.1",
31 "node-machine-id": "^1.1.10", 31 "node-machine-id": "^1.1.10",
32 "node-natural-sort": "^0.8.6", 32 "node-natural-sort": "^0.8.6",
33 "numeral": "^2.0.6", 33 "numeral": "^2.0.6",
34 "nunjucks": "^3.0.1", 34 "nunjucks": "^3.0.1",
35 "redis": "^2.8.0", 35 "redis": "^2.8.0",
36 "request": "^2.81.0", 36 "request": "^2.81.0",
37 "sha1": "^1.1.1", 37 "sha1": "^1.1.1",
38 "simple-git": "^1.80.1", 38 "simple-git": "^1.80.1",
39 "strftime": "^0.10.0", 39 "strftime": "^0.10.0",
40 "uniqid": "^4.1.1", 40 "uniqid": "^4.1.1",
41 "uuid": "^3.1.0", 41 "uuid": "^3.1.0",
42 "winston": "^2.3.1", 42 "winston": "^2.3.1",
43 "winston-circular-buffer": "^1.0.0", 43 "winston-circular-buffer": "^1.0.0",
44 "winston-daily-rotate-file": "^1.4.6" 44 "winston-daily-rotate-file": "^1.4.6"
45 } 45 }
46 } 46 }
47 47