-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PP-11682 Add the new connector axios client
- Adding this so that we can slowly transiton everything to this new version of the connector client using Axios. - At the moment, nothing is using this for now. - This is the first PR of many. - In the following PRs, plan to add updated unit tests. - Then transition the controllers to start using this new connector Axios client. - Once everything has transitioned over, the old connector client will be removed.
- Loading branch information
Showing
1 changed file
with
303 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,303 @@ | ||
'use strict' | ||
|
||
const logger = require('../../utils/logger')(__filename) | ||
const { Client } = require('@govuk-pay/pay-js-commons/lib/utils/axios-base-client/axios-base-client') | ||
const { configureClient } = require('./base/config') | ||
const requestLogger = require('../../utils/request-logger') | ||
const { getCounter } = require('../../metrics/graphite-reporter') | ||
|
||
const METRICS_PREFIX = 'internal-rest-call.connector' | ||
const SERVICE_NAME = 'connector' | ||
const WALLET_AUTH_PATH = '/v1/frontend/charges/{chargeId}/wallets/{walletType}' | ||
const CARD_AUTH_PATH = '/v1/frontend/charges/{chargeId}/cards' | ||
const CARD_3DS_PATH = '/v1/frontend/charges/{chargeId}/3ds' | ||
const CARD_STATUS_PATH = '/v1/frontend/charges/{chargeId}/status' | ||
const CARD_CAPTURE_PATH = '/v1/frontend/charges/{chargeId}/capture' | ||
const CARD_CANCEL_PATH = '/v1/frontend/charges/{chargeId}/cancel' | ||
const CARD_FIND_BY_TOKEN_PATH = '/v1/frontend/tokens/{chargeTokenId}' | ||
const TOKEN_USED_PATH = '/v1/frontend/tokens/{chargeTokenId}/used' | ||
const CARD_CHARGE_PATH = '/v1/frontend/charges/{chargeId}' | ||
const WORLDPAY_3DS_FLEX_JWT_PATH = '/v1/frontend/charges/{chargeId}/worldpay/3ds-flex/ddc' | ||
|
||
const client = new Client(SERVICE_NAME) | ||
|
||
let baseUrl | ||
|
||
/** @private */ | ||
const _getFindChargeUrlFor = chargeId => baseUrl + CARD_CHARGE_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getAuthUrlFor = chargeId => baseUrl + CARD_AUTH_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getWalletAuthUrlFor = (chargeId, walletType) => { | ||
const walletAuthUrl = baseUrl + WALLET_AUTH_PATH | ||
.replace('{chargeId}', chargeId) | ||
.replace('{walletType}', walletType) | ||
return walletAuthUrl | ||
} | ||
|
||
/** @private */ | ||
const _getThreeDsFor = chargeId => baseUrl + CARD_3DS_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getUpdateStatusUrlFor = chargeId => baseUrl + CARD_STATUS_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getCaptureUrlFor = chargeId => baseUrl + CARD_CAPTURE_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getCancelUrlFor = chargeId => baseUrl + CARD_CANCEL_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getFindByTokenUrlFor = tokenId => baseUrl + CARD_FIND_BY_TOKEN_PATH.replace('{chargeTokenId}', tokenId) | ||
|
||
/** @private */ | ||
const _markUsedTokenUrl = tokenId => baseUrl + TOKEN_USED_PATH.replace('{chargeTokenId}', tokenId) | ||
|
||
/** @private */ | ||
const _getPatchUrlFor = chargeId => baseUrl + CARD_CHARGE_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
const _getWorldpay3dsFlexUrlFor = chargeId => baseUrl + WORLDPAY_3DS_FLEX_JWT_PATH.replace('{chargeId}', chargeId) | ||
|
||
/** @private */ | ||
async function _putConnector (url, payload, description, loggingFields = {}, callingFunctionName) { | ||
const startTime = new Date() | ||
const context = { | ||
...loggingFields, | ||
url: url, | ||
method: 'PUT', | ||
description: description, | ||
service: SERVICE_NAME | ||
} | ||
requestLogger.logRequestStart(context, loggingFields) | ||
try { | ||
configureClient(client, url) | ||
const response = await client.put( url, payload, description ) | ||
logger.info('PUT to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
incrementStatusCodeCounter(callingFunctionName, response.status) | ||
if (response.status > 499 && response.status < 600) { | ||
logger.error(`Error communicating with ${url}`, { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'PUT', | ||
status_code: response.status, | ||
url: url | ||
}) | ||
} | ||
return response | ||
} catch (err) { | ||
logger.info('PUT to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
logger.error('Calling connector threw exception', { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'PUT', | ||
url: url, | ||
error: err | ||
}) | ||
incrementStatusCodeCounter(callingFunctionName, 'error') | ||
throw err | ||
} | ||
} | ||
|
||
/** @private */ | ||
async function _postConnector (url, payload, description, loggingFields = {}, callingFunctionName) { | ||
const startTime = new Date() | ||
const context = { | ||
url: url, | ||
method: 'POST', | ||
description: description, | ||
service: SERVICE_NAME | ||
} | ||
requestLogger.logRequestStart(context, loggingFields) | ||
try { | ||
configureClient(client, url) | ||
|
||
const response = await client.post(url, payload, description) | ||
logger.info('POST to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
incrementStatusCodeCounter(callingFunctionName, response.status) | ||
if (response.status > 499 && response.status < 600) { | ||
logger.error(`Error communicating with ${url}`, { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'POST', | ||
status_code: response.status, | ||
url: url | ||
}) | ||
} | ||
console.log('1 - return response: ', response) | ||
return response | ||
} catch (err) { | ||
logger.info('POST to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
logger.error('Calling connector threw exception', { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'POST', | ||
url: url, | ||
error: err | ||
}) | ||
incrementStatusCodeCounter(callingFunctionName, 'error') | ||
throw err | ||
} | ||
} | ||
|
||
/** @private */ | ||
async function _patchConnector (url, payload, description, loggingFields = {}, callingFunctionName) { | ||
const startTime = new Date() | ||
const context = { | ||
url: url, | ||
method: 'PATCH', | ||
description: description, | ||
service: SERVICE_NAME | ||
} | ||
requestLogger.logRequestStart(context, loggingFields) | ||
try { | ||
configureClient(client, url) | ||
|
||
const response = await client.patch( url, payload, description) | ||
logger.info('PATCH to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
incrementStatusCodeCounter(callingFunctionName, response.status) | ||
if (response.status > 499 && response.status < 600) { | ||
logger.error(`Error communicating with ${url}`, { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'PATCH', | ||
status_code: response.status, | ||
url: url | ||
}) | ||
} | ||
return response | ||
} catch (err) { | ||
logger.info('PATCH %s to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
logger.error('Calling connector threw exception', { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'PATCH', | ||
url: url, | ||
error: err | ||
}) | ||
incrementStatusCodeCounter(callingFunctionName, 'error') | ||
throw err | ||
} | ||
} | ||
|
||
/** @private */ | ||
async function _getConnector (url, description, loggingFields = {}, callingFunctionName) { | ||
const startTime = new Date() | ||
const context = { | ||
url: url, | ||
method: 'GET', | ||
description: description, | ||
service: SERVICE_NAME | ||
} | ||
requestLogger.logRequestStart(context, loggingFields) | ||
try { | ||
configureClient(client, url) | ||
|
||
const response = await client.get(`${url}`, description) | ||
logger.info('GET to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
incrementStatusCodeCounter(callingFunctionName, response.status) | ||
if (response.status !== 200) { | ||
logger.error(`Error communicating with ${url}`, { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'GET', | ||
status_code: response.status, | ||
url: url | ||
}) | ||
} | ||
return response | ||
} catch (err) { | ||
logger.info('GET to %s ended - total time %dms', url, new Date() - startTime, loggingFields) | ||
logger.error('Calling connector threw exception', { | ||
...loggingFields, | ||
service: 'connector', | ||
method: 'GET', | ||
url: url, | ||
error: err | ||
}) | ||
incrementStatusCodeCounter(callingFunctionName, 'error') | ||
throw err | ||
} | ||
} | ||
|
||
const incrementStatusCodeCounter = (callingFunctionName, statusCode) => { | ||
getCounter(`${METRICS_PREFIX}.${callingFunctionName}.${statusCode}`).inc() | ||
} | ||
|
||
// POST functions | ||
const threeDs = (chargeOptions, loggingFields = {}) => { | ||
const threeDsUrl = _getThreeDsFor(chargeOptions.chargeId) | ||
return _postConnector(threeDsUrl, chargeOptions.payload, '3ds', loggingFields, 'threeDs') | ||
} | ||
|
||
const chargeAuth = (chargeOptions, loggingFields = {}) => { | ||
const authUrl = _getAuthUrlFor(chargeOptions.chargeId) | ||
return _postConnector(authUrl, chargeOptions.payload, 'create charge', loggingFields, 'chargeAuth') | ||
} | ||
|
||
const chargeAuthWithWallet = (chargeOptions, loggingFields = {}) => { | ||
const authUrl = _getWalletAuthUrlFor(chargeOptions.chargeId, chargeOptions.wallet) | ||
return _postConnector(authUrl, chargeOptions.payload, 'create charge using e-wallet payment', loggingFields, 'chargeAuthWithWallet') | ||
} | ||
|
||
const capture = (chargeOptions, loggingFields = {}) => { | ||
const captureUrl = _getCaptureUrlFor(chargeOptions.chargeId) | ||
return _postConnector(captureUrl, null, 'do capture', loggingFields, 'capture') | ||
} | ||
|
||
const cancel = (chargeOptions, loggingFields = {}) => { | ||
const cancelUrl = _getCancelUrlFor(chargeOptions.chargeId) | ||
return _postConnector(cancelUrl, null, 'cancel charge', loggingFields, 'cancel') | ||
} | ||
|
||
// PUT functions | ||
const updateStatus = (chargeOptions, loggingFields = {}) => { | ||
const updateStatusUrl = _getUpdateStatusUrlFor(chargeOptions.chargeId) | ||
return _putConnector(updateStatusUrl, chargeOptions.payload, 'update status', loggingFields, 'updateStatus') | ||
} | ||
|
||
// PATCH functions | ||
const patch = (chargeOptions, loggingFields = {}) => { | ||
const patchUrl = _getPatchUrlFor(chargeOptions.chargeId) | ||
return _patchConnector(patchUrl, chargeOptions.payload, 'patch', loggingFields, 'patch') | ||
} | ||
|
||
// GET functions | ||
const findCharge = (chargeOptions, loggingFields = {}) => { | ||
const findChargeUrl = _getFindChargeUrlFor(chargeOptions.chargeId) | ||
return _getConnector(findChargeUrl, 'find charge', loggingFields, 'findCharge') | ||
} | ||
|
||
const findByToken = (chargeOptions, loggingFields = {}) => { | ||
const findByTokenUrl = _getFindByTokenUrlFor(chargeOptions.tokenId) | ||
return _getConnector(findByTokenUrl, 'find by token', loggingFields, 'findByToken') | ||
} | ||
|
||
const getWorldpay3dsFlexJwt = (chargeOptions, loggingFields = {}) => { | ||
const getWorldpay3dsFlexJwtUrl = _getWorldpay3dsFlexUrlFor(chargeOptions.chargeId) | ||
return _getConnector(getWorldpay3dsFlexJwtUrl, 'get Worldpay 3DS Flex DDC JWT', loggingFields, 'getWorldpay3dsFlexJwt') | ||
} | ||
|
||
const markTokenAsUsed = (chargeOptions, loggingFields = {}) => { | ||
const markUsedTokenUrl = _markUsedTokenUrl(chargeOptions.tokenId) | ||
return _postConnector(markUsedTokenUrl, undefined, 'mark token as used', loggingFields, 'markTokenAsUsed') | ||
} | ||
|
||
module.exports = function (clientOptions = {}) { | ||
baseUrl = clientOptions.baseUrl || process.env.CONNECTOR_HOST | ||
return { | ||
chargeAuth, | ||
chargeAuthWithWallet, | ||
threeDs, | ||
updateStatus, | ||
findCharge, | ||
capture, | ||
cancel, | ||
findByToken, | ||
patch, | ||
markTokenAsUsed, | ||
getWorldpay3dsFlexJwt | ||
} | ||
} |