Skip to content

Commit 05c2fcb

Browse files
authored
RGOPS-4757 : add DNS resolution to check for live nodes + fixes (#11)
1 parent c8f9cb9 commit 05c2fcb

File tree

3 files changed

+89
-67
lines changed

3 files changed

+89
-67
lines changed

config/rgProperties.json

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"serviceSettings": {
3-
"ROCKETGATE_SERVLET": "/gateway/servlet/ServiceDispatcherAccess",
3+
"ROCKETGATE_SERVLET": "gateway/servlet/ServiceDispatcherAccess",
44
"ROCKETGATE_CONNECT_TIMEOUT": 10,
55
"ROCKETGATE_READ_TIMEOUT": 90,
66
"ROCKETGATE_PROTOCOL": "https",
77
"ROCKETGATE_PORTNO": "443",
8-
"ROCKETGATE_USER_AGENT": "RG Client NodeJS K2.2",
8+
"ROCKETGATE_USER_AGENT": "RG Client NodeJS",
99
"LIVE_HOST": "gateway.rocketgate.com",
1010
"LIVE_HOST_16": "gateway-16.rocketgate.com",
1111
"LIVE_HOST_17": "gateway-17.rocketgate.com",
1212
"TEST_HOST": "dev-gateway.rocketgate.com",
13-
"VERSION_NUMBER": "K2.2"
13+
"VERSION_NUMBER": "K2.3"
1414
},
1515
"responseSettings": {
1616
"VERSION_INDICATOR": "version",
@@ -72,13 +72,6 @@
7272
"112": "Declined – Invalid Expiration",
7373
"113": "Declined – Bank Unavailable",
7474
"114": "Declined – AVS",
75-
"107": "Declined Expired Card",
76-
"108": "Declined – Call",
77-
"109": "Declined – Pickup Card",
78-
"110": "Declined – Excessive Use",
79-
"111": "Declined – Invalid card",
80-
"112": "Declined – Invalid Expiration",
81-
"113": "Declined – Bank Unavailable",
8275
"117": "Declined – AVS",
8376
"123": "Declined – User Declined",
8477
"150": "Declined – AVS",

lib/gatewayService.js

Lines changed: 78 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var _request = require('request'),
2+
dns = require('node:dns'),
23
serviceSettings = require('../config/config').serviceSettings,
34
responseSettings = require('../config/config').responseSettings,
45
utils = require('./utils');
@@ -157,9 +158,6 @@ function GatewayService(options) {
157158
if (request.hasOwnProperty('portNo') && request.portNo !== null) {
158159
urlPortNo = request.portNo;
159160
}
160-
if (request.hasOwnProperty('portNo') && request.portNo !== null) {
161-
urlPortNo = request.portNo;
162-
}
163161
if (request.hasOwnProperty('gatewayConnectTimeout') && request.gatewayConnectTimeout !== null) {
164162
connectTimeout = request.gatewayConnectTimeout;
165163
}
@@ -173,36 +171,37 @@ function GatewayService(options) {
173171
utils.toXML(request, function(err, requestXML) {
174172
options = {
175173
method: "POST",
176-
uri: urlProtocol + "://" + serverName + urlServlet,
174+
uri: urlProtocol + "://" + serverName + ":" + urlPortNo + "/" + urlServlet,
177175
body: requestXML,
178176
headers: {
179177
'Content-Type': 'text/xml',
180-
'User-Agent': serviceSettings.ROCKETGATE_USER_AGENT
178+
'User-Agent': serviceSettings.ROCKETGATE_USER_AGENT + " " + serviceSettings.VERSION_NUMBER
181179
},
182180
timeout: connectTimeout * 1000
183181
};
184182

185183
_request(options, function(err, res, body) {
186-
var responseCode = null;
184+
var responseCode = null, errorMessage;
187185

188186
if (err) {
189-
console.log('error: ', err);
190-
console.log(options);
187+
errorMessage = err;
188+
} else if (res.statusCode < 200 || res.statusCode > 299) {
189+
errorMessage = res.statusCode + " " + res.statusMessage;
191190
} else {
192-
utils.fromXML(body, function(err, json) {
191+
utils.fromXML(body, function (err, json) {
193192
if (!err && !!json) {
194193
response = json;
195194
responseCode = json[responseSettings.RESPONSE_CODE];
196195
} else {
197-
console.log('Impossible to parse body: ', err, { options, body });
196+
errorMessage = "Can't parse response body as XML";
198197
}
199198
});
200199
}
201200
if (responseCode === null) {
202-
responseCode = "4";
203-
response[responseSettings.EXCEPTION] = body;
201+
responseCode = "3";
202+
response[responseSettings.EXCEPTION] = errorMessage;
204203
response[responseSettings.RESPONSE_CODE] = responseCode;
205-
response[responseSettings.REASON_CODE] = "400";
204+
response[responseSettings.REASON_CODE] = "304"; // REASON_RESPONSE_READ_ERROR
206205
}
207206
callback(responseCode, request, response);
208207
});
@@ -217,17 +216,14 @@ function GatewayService(options) {
217216
* @param {Function} callback [description]
218217
*/
219218
function performTransaction(request, response, callback) {
220-
var index = null,
221-
swapper = null,
222-
serverName = gatewaySettings.rocketGateHost;
219+
var serverName = null;
223220

224221
var url = require('url');
225222
var fullUrl = request.gatewayURL;
226223
var embeddedFieldsToken = request.embeddedFieldsToken;
227224

228225
fullUrl = fullUrl || embeddedFieldsToken;
229226
if (fullUrl) {
230-
231227
var parsedUrl = url.parse(fullUrl, true);
232228
if (!request.gatewayServer) {
233229
request.gatewayServer = parsedUrl.host;
@@ -256,49 +252,75 @@ function GatewayService(options) {
256252
delete request.failedGUID;
257253
}
258254

259-
// if (serverName.length > 1) {
260-
// index = Math.floor(Math.random() * (serverName.length + 1));
261-
//
262-
// if (index > 0) {
263-
// swapper = serverName[0];
264-
// serverName[0] = serverName[index];
265-
// serverName[index] = swapper;
266-
// }
267-
// }
268-
269-
index = 0;
270-
sendTransaction(serverName[index], request, response, function(responseCode, request, response) {
271-
if (responseCode == "0") {
272-
// transaction succeeded
273-
return callback(true, request, response);
274-
} else if (responseCode != "3") {
275-
// transaction failed
276-
return callback(false, request, response);
277-
} else {
278-
// try again
279-
request.failedServer = serverName[index];
280-
request.failedResponseCode = response[responseSettings.RESPONSE_CODE];
281-
request.failedReasonCode = response[responseSettings.REASON_CODE];
282-
request.failedGUID = response[responseSettings.TRANSACT_ID];
283-
284-
// if this is the last one to try, send it back
285-
if (index == serverName.length - 1) {
255+
function _perform(serverNames) {
256+
var index = 0;
257+
sendTransaction(serverNames[index], request, response, function (responseCode, request, response) {
258+
if (responseCode == "0") {
259+
// transaction succeeded
260+
return callback(true, request, response);
261+
} else if (responseCode != "3") {
262+
// transaction failed
286263
return callback(false, request, response);
287264
} else {
288-
//otherwise, give it one more try
289-
index++;
290-
sendTransaction(serverName[index], request, response, function(responseCode, request, response) {
291-
if (responseCode == "0") {
292-
// transaction succeeded
293-
return callback(true, request, response);
294-
} else {
295-
// transaction failed
296-
return callback(false, request, response);
265+
// try again
266+
request.failedServer = serverNames[index];
267+
request.failedResponseCode = response[responseSettings.RESPONSE_CODE];
268+
request.failedReasonCode = response[responseSettings.REASON_CODE];
269+
request.failedGUID = response[responseSettings.TRANSACT_ID];
270+
271+
// if this is the last one to try, send it back
272+
if (index == serverNames.length - 1) {
273+
return callback(false, request, response);
274+
} else {
275+
//otherwise, give it one more try
276+
index++;
277+
sendTransaction(serverNames[index], request, response, function (responseCode, request, response) {
278+
if (responseCode == "0") {
279+
// transaction succeeded
280+
return callback(true, request, response);
281+
} else {
282+
// transaction failed
283+
return callback(false, request, response);
284+
}
285+
});
286+
}
287+
}
288+
});
289+
}
290+
291+
if (serverName != null) {
292+
// if is set explicitly via request
293+
_perform(serverName)
294+
} else if (gatewaySettings.rocketGateDNS !== serviceSettings.LIVE_HOST) {
295+
_perform(gatewaySettings.rocketGateHost);
296+
} else {
297+
dns.resolve4(serviceSettings.LIVE_HOST, (err, records) => {
298+
if (err != null || !records || records.length === 0) {
299+
// DNS resolution failed, use default
300+
_perform(gatewaySettings.rocketGateHost)
301+
} else {
302+
var liveServerNames = [];
303+
for (var i = 0; i < records.length; i++) {
304+
var record = records[i];
305+
if ('69.20.127.91' === record) {
306+
liveServerNames.push(serviceSettings.LIVE_HOST_16);
307+
} else if ('72.32.126.131' === record) {
308+
liveServerNames.push(serviceSettings.LIVE_HOST_17);
297309
}
298-
});
310+
}
311+
if (liveServerNames.length === 0) {
312+
// DNS resolution failed, use default
313+
_perform(gatewaySettings.rocketGateHost)
314+
} else {
315+
if (liveServerNames.length > 1) {
316+
// distribute load by randomization
317+
utils.shuffleArray(liveServerNames)
318+
}
319+
_perform(liveServerNames);
320+
}
299321
}
300-
}
301-
});
322+
});
323+
}
302324
}
303325

304326
/**

lib/utils.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ var exports = module.exports = {
1616
} catch (err) {
1717
callback(err);
1818
}
19+
},
20+
shuffleArray: function (array) {
21+
for (var i = array.length - 1; i > 0; i--) {
22+
var j = Math.floor(Math.random() * (i + 1));
23+
var temp = array[i];
24+
array[i] = array[j];
25+
array[j] = temp;
26+
}
1927
}
20-
2128
};

0 commit comments

Comments
 (0)