Skip to content

Commit

Permalink
RGOPS-4757 : add DNS resolution to check for live nodes + fixes (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
volodymyr-rg authored Feb 14, 2024
1 parent c8f9cb9 commit 05c2fcb
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 67 deletions.
13 changes: 3 additions & 10 deletions config/rgProperties.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"serviceSettings": {
"ROCKETGATE_SERVLET": "/gateway/servlet/ServiceDispatcherAccess",
"ROCKETGATE_SERVLET": "gateway/servlet/ServiceDispatcherAccess",
"ROCKETGATE_CONNECT_TIMEOUT": 10,
"ROCKETGATE_READ_TIMEOUT": 90,
"ROCKETGATE_PROTOCOL": "https",
"ROCKETGATE_PORTNO": "443",
"ROCKETGATE_USER_AGENT": "RG Client NodeJS K2.2",
"ROCKETGATE_USER_AGENT": "RG Client NodeJS",
"LIVE_HOST": "gateway.rocketgate.com",
"LIVE_HOST_16": "gateway-16.rocketgate.com",
"LIVE_HOST_17": "gateway-17.rocketgate.com",
"TEST_HOST": "dev-gateway.rocketgate.com",
"VERSION_NUMBER": "K2.2"
"VERSION_NUMBER": "K2.3"
},
"responseSettings": {
"VERSION_INDICATOR": "version",
Expand Down Expand Up @@ -72,13 +72,6 @@
"112": "Declined – Invalid Expiration",
"113": "Declined – Bank Unavailable",
"114": "Declined – AVS",
"107": "Declined Expired Card",
"108": "Declined – Call",
"109": "Declined – Pickup Card",
"110": "Declined – Excessive Use",
"111": "Declined – Invalid card",
"112": "Declined – Invalid Expiration",
"113": "Declined – Bank Unavailable",
"117": "Declined – AVS",
"123": "Declined – User Declined",
"150": "Declined – AVS",
Expand Down
134 changes: 78 additions & 56 deletions lib/gatewayService.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var _request = require('request'),
dns = require('node:dns'),
serviceSettings = require('../config/config').serviceSettings,
responseSettings = require('../config/config').responseSettings,
utils = require('./utils');
Expand Down Expand Up @@ -157,9 +158,6 @@ function GatewayService(options) {
if (request.hasOwnProperty('portNo') && request.portNo !== null) {
urlPortNo = request.portNo;
}
if (request.hasOwnProperty('portNo') && request.portNo !== null) {
urlPortNo = request.portNo;
}
if (request.hasOwnProperty('gatewayConnectTimeout') && request.gatewayConnectTimeout !== null) {
connectTimeout = request.gatewayConnectTimeout;
}
Expand All @@ -173,36 +171,37 @@ function GatewayService(options) {
utils.toXML(request, function(err, requestXML) {
options = {
method: "POST",
uri: urlProtocol + "://" + serverName + urlServlet,
uri: urlProtocol + "://" + serverName + ":" + urlPortNo + "/" + urlServlet,
body: requestXML,
headers: {
'Content-Type': 'text/xml',
'User-Agent': serviceSettings.ROCKETGATE_USER_AGENT
'User-Agent': serviceSettings.ROCKETGATE_USER_AGENT + " " + serviceSettings.VERSION_NUMBER
},
timeout: connectTimeout * 1000
};

_request(options, function(err, res, body) {
var responseCode = null;
var responseCode = null, errorMessage;

if (err) {
console.log('error: ', err);
console.log(options);
errorMessage = err;
} else if (res.statusCode < 200 || res.statusCode > 299) {
errorMessage = res.statusCode + " " + res.statusMessage;
} else {
utils.fromXML(body, function(err, json) {
utils.fromXML(body, function (err, json) {
if (!err && !!json) {
response = json;
responseCode = json[responseSettings.RESPONSE_CODE];
} else {
console.log('Impossible to parse body: ', err, { options, body });
errorMessage = "Can't parse response body as XML";
}
});
}
if (responseCode === null) {
responseCode = "4";
response[responseSettings.EXCEPTION] = body;
responseCode = "3";
response[responseSettings.EXCEPTION] = errorMessage;
response[responseSettings.RESPONSE_CODE] = responseCode;
response[responseSettings.REASON_CODE] = "400";
response[responseSettings.REASON_CODE] = "304"; // REASON_RESPONSE_READ_ERROR
}
callback(responseCode, request, response);
});
Expand All @@ -217,17 +216,14 @@ function GatewayService(options) {
* @param {Function} callback [description]
*/
function performTransaction(request, response, callback) {
var index = null,
swapper = null,
serverName = gatewaySettings.rocketGateHost;
var serverName = null;

var url = require('url');
var fullUrl = request.gatewayURL;
var embeddedFieldsToken = request.embeddedFieldsToken;

fullUrl = fullUrl || embeddedFieldsToken;
if (fullUrl) {

var parsedUrl = url.parse(fullUrl, true);
if (!request.gatewayServer) {
request.gatewayServer = parsedUrl.host;
Expand Down Expand Up @@ -256,49 +252,75 @@ function GatewayService(options) {
delete request.failedGUID;
}

// if (serverName.length > 1) {
// index = Math.floor(Math.random() * (serverName.length + 1));
//
// if (index > 0) {
// swapper = serverName[0];
// serverName[0] = serverName[index];
// serverName[index] = swapper;
// }
// }

index = 0;
sendTransaction(serverName[index], request, response, function(responseCode, request, response) {
if (responseCode == "0") {
// transaction succeeded
return callback(true, request, response);
} else if (responseCode != "3") {
// transaction failed
return callback(false, request, response);
} else {
// try again
request.failedServer = serverName[index];
request.failedResponseCode = response[responseSettings.RESPONSE_CODE];
request.failedReasonCode = response[responseSettings.REASON_CODE];
request.failedGUID = response[responseSettings.TRANSACT_ID];

// if this is the last one to try, send it back
if (index == serverName.length - 1) {
function _perform(serverNames) {
var index = 0;
sendTransaction(serverNames[index], request, response, function (responseCode, request, response) {
if (responseCode == "0") {
// transaction succeeded
return callback(true, request, response);
} else if (responseCode != "3") {
// transaction failed
return callback(false, request, response);
} else {
//otherwise, give it one more try
index++;
sendTransaction(serverName[index], request, response, function(responseCode, request, response) {
if (responseCode == "0") {
// transaction succeeded
return callback(true, request, response);
} else {
// transaction failed
return callback(false, request, response);
// try again
request.failedServer = serverNames[index];
request.failedResponseCode = response[responseSettings.RESPONSE_CODE];
request.failedReasonCode = response[responseSettings.REASON_CODE];
request.failedGUID = response[responseSettings.TRANSACT_ID];

// if this is the last one to try, send it back
if (index == serverNames.length - 1) {
return callback(false, request, response);
} else {
//otherwise, give it one more try
index++;
sendTransaction(serverNames[index], request, response, function (responseCode, request, response) {
if (responseCode == "0") {
// transaction succeeded
return callback(true, request, response);
} else {
// transaction failed
return callback(false, request, response);
}
});
}
}
});
}

if (serverName != null) {
// if is set explicitly via request
_perform(serverName)
} else if (gatewaySettings.rocketGateDNS !== serviceSettings.LIVE_HOST) {
_perform(gatewaySettings.rocketGateHost);
} else {
dns.resolve4(serviceSettings.LIVE_HOST, (err, records) => {
if (err != null || !records || records.length === 0) {
// DNS resolution failed, use default
_perform(gatewaySettings.rocketGateHost)
} else {
var liveServerNames = [];
for (var i = 0; i < records.length; i++) {
var record = records[i];
if ('69.20.127.91' === record) {
liveServerNames.push(serviceSettings.LIVE_HOST_16);
} else if ('72.32.126.131' === record) {
liveServerNames.push(serviceSettings.LIVE_HOST_17);
}
});
}
if (liveServerNames.length === 0) {
// DNS resolution failed, use default
_perform(gatewaySettings.rocketGateHost)
} else {
if (liveServerNames.length > 1) {
// distribute load by randomization
utils.shuffleArray(liveServerNames)
}
_perform(liveServerNames);
}
}
}
});
});
}
}

/**
Expand Down
9 changes: 8 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ var exports = module.exports = {
} catch (err) {
callback(err);
}
},
shuffleArray: function (array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}

};

0 comments on commit 05c2fcb

Please sign in to comment.