Skip to content

Commit

Permalink
Merge pull request #572 from Travelport-Ukraine/master
Browse files Browse the repository at this point in the history
1.12.5 IAI 1125 Astra
  • Loading branch information
dchertousov authored Mar 25, 2022
2 parents 40125ab + fb083b3 commit 7ab4761
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 8 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "uapi-json",
"version": "1.12.4",
"version": "1.12.5",
"description": "Travelport Universal API",
"main": "src/",
"files": [
Expand Down
54 changes: 52 additions & 2 deletions src/Services/Terminal/Terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ const TERMINAL_STATE_ERROR = 'TERMINAL_STATE_ERROR';
const screenFunctions = screenLib({ cursor: '><' });
const autoCloseTerminals = [];

const ERROR_INFO_SUFFIX = 'ErrorInfo';
const ERROR_CODE_SUFFIX = 'Code';
const RETRY_CODES_LIST = ['14058'];

const DEFAULT_RETRY_TIMES = 3;

// Adding event handler on beforeExit and exit process events to process open terminals
process.on('beforeExit', () => {
Promise.all(
Expand Down Expand Up @@ -67,6 +73,48 @@ process.on('exit', () => {
});
});

const getErrorTagPrefix = (detailObject) => {
const [field] = Object.keys(detailObject);
const [prefix] = field.split(':');

return prefix;
};

const isErrorRetriable = (e) => {
if (!e.causedBy || !e.causedBy.data || !e.causedBy.data.detail) {
return false;
}

const { detail } = e.causedBy.data;
const versionPrefix = getErrorTagPrefix(detail);
const errorCode = detail[`${versionPrefix}:${ERROR_INFO_SUFFIX}`]
&& detail[`${versionPrefix}:${ERROR_INFO_SUFFIX}`][`${versionPrefix}:${ERROR_CODE_SUFFIX}`];

return (errorCode && RETRY_CODES_LIST.includes(errorCode));
};

const commandRetry = async ({
service,
command,
sessionToken,
times = DEFAULT_RETRY_TIMES,
}) => {
try {
return await service.executeCommand({ command, sessionToken });
} catch (e) {
if (!isErrorRetriable(e) || times <= 0) {
throw e;
}

return commandRetry({
service,
command,
sessionToken,
times: times - 1,
});
}
};

module.exports = function (settings) {
const service = terminalService(validateServiceSettings(settings));
const log = (settings.options && settings.options.logFunction) || console.log;
Expand All @@ -84,6 +132,7 @@ module.exports = function (settings) {
terminalState: TERMINAL_STATE_NONE,
sessionToken: token,
};

// Processing response with MD commands
const processResponse = (response, stopMD, previousResponse = null) => {
const processedResponse = previousResponse
Expand All @@ -95,7 +144,8 @@ module.exports = function (settings) {
if (stopMD(processedResponse)) {
return processedResponse;
}
return service.executeCommand({
return commandRetry({
service,
sessionToken: state.sessionToken,
command: 'MD',
}).then(
Expand Down Expand Up @@ -162,7 +212,7 @@ module.exports = function (settings) {
log(`[${terminalId}] Terminal request:\n${command}`);
}

const screen = await service.executeCommand({ command, sessionToken });
const screen = await commandRetry({ service, command, sessionToken });
const response = await processResponse(screen, stopMD);

if (debug) {
Expand Down
21 changes: 17 additions & 4 deletions test/Terminal/Terminal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const sinonChai = require('sinon-chai');
const proxyquire = require('proxyquire');
const config = require('../testconfig');
const uAPI = require('../../src');
const { RequestRuntimeError } = require('../../src/Request/RequestErrors');

chai.use(sinonChai);
process.setMaxListeners(20);
Expand Down Expand Up @@ -49,6 +50,14 @@ const getTerminalResponse = p => new Promise((resolve, reject) => {
// Token const
const token = 'TOKEN';

const sessionError = {
detail: {
'common_v33_0:ErrorInfo': {
'common_v33_0:Code': '14058',
}
}
};

// Spied functions
const getSessionToken = sinon.spy(() => Promise.resolve({ sessionToken: token }));
const executeCommandSlow = sinon.spy((params) => {
Expand Down Expand Up @@ -84,24 +93,27 @@ const executeCommandOk = sinon.spy((params) => {
return getTerminalResponse('ERR');
}
});
const mdCallMdIssues = sinon.stub();
const executeCommandMdIssues = sinon.spy((params) => {
expect(params).to.be.an('object');
expect(params.sessionToken).to.equal(token);
expect(params.command).to.be.a('string');

const mdCall = sinon.stub();
mdCall.onCall(0).returns(
mdCallMdIssues.onCall(0).returns(
getTerminalResponse('set02/HFF-P2')
);
mdCall.onCall(1).returns(
mdCallMdIssues.onCall(1).throws(
new RequestRuntimeError.UnhandledError(null, new TerminalRuntimeError(sessionError))
);
mdCallMdIssues.onCall(2).returns(
getTerminalResponse('set02/HFF-P3')
);

switch (params.command) {
case '*HFF':
return getTerminalResponse('set02/HFF-P1');
case 'MD':
return mdCall();
return mdCallMdIssues();
default:
if (params.command.match(/^SEM/)) {
return getTerminalResponse('SEM');
Expand All @@ -123,6 +135,7 @@ const executeCommandEmulationFailed = sinon.spy((params) => {
return getTerminalResponse('ERR');
}
});

const closeSession = sinon.spy(() => Promise.resolve(true));
const closeSessionError = sinon.spy(() => Promise.reject(new Error('Error closing session')));

Expand Down

0 comments on commit 7ab4761

Please sign in to comment.