Compare View

switch
from
...
to
 
Commits (5)

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