Compare View

switch
from
...
to
 
Commits (3)

Changes

Showing 4 changed files Inline Diff

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