Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LegacyRequestLib #143

Merged
merged 5 commits into from
Mar 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ TACTICAL_IDM_URL=http://localhost:8003
PERMIT_REPOSITORY_URL=http://localhost:8004
RETURNS_URL=http://localhost:8006

# JWT Auth token shared by all legacy external services
LEGACY_AUTH_TOKEN=longvalueofnumbersandletters.inbothcases.splitin3by2periods

# External Charging Module JWT (AWS Cognito) service
CHARGING_MODULE_TOKEN_URL=https://myinstance.amazoncognito.com
CHARGING_MODULE_TOKEN_USERNAME=valuefullofnumbersandlettersinlowercase
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
TACTICAL_IDM_URL: http://localhost:8003
PERMIT_REPOSITORY_URL: http://localhost:8004
RETURNS_URL: http://localhost:8006
# JWT Auth token shared by all legacy external services
LEGACY_AUTH_TOKEN: longvalueofnumbersandletters.inbothcases.splitin3by2periods
# External Charging Module JWT (AWS Cognito) service
CHARGING_MODULE_TOKEN_URL: https://myinstance.amazoncognito.com
CHARGING_MODULE_TOKEN_USERNAME: valuefullofnumbersandlettersinlowercase
Expand Down
8 changes: 4 additions & 4 deletions app/lib/charging-module-request.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ async function get (path) {
}

/**
* Sends a PATCH request to the Charging Module for the provided route
* Sends a PATCH request to the Charging Module for the provided path
*
* @param {string} path The route to send the request to (do not include the starting /)
* @param {string} path The path to send the request to (do not include the starting /)
*
* @returns {Object} result An object representing the result of the request
* @returns {boolean} result.succeeded Whether the request was successful
Expand All @@ -39,7 +39,7 @@ async function patch (path) {
}

/**
* Sends a POST request to the Charging Module for the provided route
* Sends a POST request to the Charging Module for the provided path
*
* @param {string} path The path to send the request to (do not include the starting /)
* @param {Object} [body] The body of the request
Expand All @@ -55,7 +55,7 @@ async function post (path, body = {}) {
}

/**
* Sends a request to the Charging Module to the provided using the provided RequestLib method
* Sends a request to the Charging Module using the provided RequestLib method
*
* @param {string} path The path that you wish to connect to (do not include the starting /)
* @param {Object} method An instance of a RequestLib method which will be used to send the request
Expand Down
185 changes: 185 additions & 0 deletions app/lib/legacy-request.lib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
'use strict'

/**
* Use for making http requests to the legacy web services
* @module LegacyRequestLib
*/

const RequestLib = require('./request.lib.js')

const servicesConfig = require('../../config/services.config.js')

const services = {
// REPO-NAME - PM2 NAME
// water-abstraction-service - service-background
background: {
base: servicesConfig.serviceBackground.url,
api: 'water/1.0'
},
// water-abstraction-tactical-crm - tactical-crm
crm: {
base: servicesConfig.tacticalCrm.url,
api: 'crm/1.0'
},
// water-abstraction-ui - ui
external: {
base: servicesConfig.externalUi.url,
api: ''
},
// water-abstraction-tactical-idm - tactical-idm
idm: {
base: servicesConfig.tacticalIdm.url,
api: 'idm/1.0'
},
// water-abstraction-import - import
import: {
base: servicesConfig.import.url,
api: 'import/1.0'
},
// water-abstraction-ui - internal-ui
internal: {
base: servicesConfig.internalUi.url,
api: ''
},
// water-abstraction-permit-repository - permit-repository
permits: {
base: servicesConfig.permitRepository.url,
api: 'API/1.0/'
},
// water-abstraction-reporting - reporting
reporting: {
base: servicesConfig.reporting.url,
api: 'reporting/1.0'
},
// water-abstraction-returns - returns
returns: {
base: servicesConfig.returns.url,
api: 'returns/1.0'
},
// water-abstraction-service - water-api
water: {
base: servicesConfig.serviceForeground.url,
api: 'water/1.0'
}
}

/**
* Sends a GET request to the legacy service for the provided path
*
* @param {string} serviceName name of the legacy service to call (background, crm, external, idm, import, internal,
* permits, reporting, returns or water)
* @param {string} path The path to send the request to (do not include the starting /)
* @param {boolean} apiRequest whether the request is to the service's API endpoints
*
* @returns {Object} result An object representing the result of the request
* @returns {boolean} result.succeeded Whether the request was successful
* @returns {Object} result.response The legacy service's response if successful or the error response if not.
*/
async function get (serviceName, path, apiRequest = true) {
return await _sendRequest(RequestLib.get, serviceName, path, apiRequest)
}

/**
* Sends a POST request to the legacy service for the provided path
*
* @param {string} serviceName name of the legacy service to call (background, crm, external, idm, import, internal,
* permits, reporting, returns or water)
* @param {string} path the path to send the request to (do not include the starting /)
* @param {boolean} apiRequest whether the request is to the service's API endpoints
* @param {Object} [body] optional body to be sent to the service as json
*
* @returns {Object} result An object representing the result of the request
* @returns {boolean} result.succeeded Whether the request was successful
* @returns {Object} result.response The legacy service's response if successful or the error response if not.
*/
async function post (serviceName, path, apiRequest = true, body = {}) {
return await _sendRequest(RequestLib.post, serviceName, path, apiRequest, body)
}

/**
* Sends a request to a legacy service using the provided RequestLib method
*
* @param {Object} method an instance of a RequestLib method which will be used to send the request
* @param {string} serviceName name of the legacy service (see `services`)
* @param {string} path the path that you wish to connect to (do not include the starting /)
* @param {boolean} apiRequest whether the request is to the service's API endpoints
* @param {Object} body body to be sent to the service as json
*
* @returns {Object} The result of the request passed back from RequestLib
*/
async function _sendRequest (method, serviceName, path, apiRequest, body) {
const service = _service(serviceName)
const options = _requestOptions(service, apiRequest, body)

const result = await method(path, options)

return _parseResult(result)
}

function _service (serviceName) {
const service = services[serviceName.trim().toLowerCase()]

if (!service) {
throw new Error(`Request to unknown legacy service ${serviceName}`)
}

return service
}

/**
* Additional options that will be added to the default options used by RequestLib
*
* We use it to set
*
* - the base URL for the request
* - the authorization header with shared legacy JWT Auth token
* - the body (which is always a JSON object) for our POST requests
* - the option to tell Got that we expect JSON responses. This means Got will automatically handle parsing the
* response to a JSON object for us
*
* @param {Object} service which legacy service we are connecting with
* @param {boolean} apiRequest whether the request is to the service's API endpoints
* @param {Object} body the request body if applicable
*
* @returns Legacy specific options to be passed to RequestLib
*/
function _requestOptions (service, apiRequest, body) {
const prefixUrl = apiRequest ? new URL(service.api, service.base).href : service.base

return {
prefixUrl,
headers: {
authorization: `Bearer ${servicesConfig.legacyAuthToken}`
},
responseType: 'json',
json: body
}
}

/**
* Parses the charging module response returned from RequestLib
*
* @param {Object} result The result object returned by RequestLib
*
* @returns {Object} If result was not an error, a parsed version of the response
*/
function _parseResult (result) {
const { body, statusCode } = result.response

if (body) {
return {
succeeded: result.succeeded,
response: {
statusCode,
body
}
}
}

return result
}

module.exports = {
get,
post
}
31 changes: 16 additions & 15 deletions app/services/health/info.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const exec = util.promisify(ChildProcess.exec)

const ChargingModuleRequestLib = require('../../lib/charging-module-request.lib.js')
const RequestLib = require('../../lib/request.lib.js')
const LegacyRequestLib = require('../../lib/legacy-request.lib.js')

const servicesConfig = require('../../../config/services.config.js')

Expand Down Expand Up @@ -103,27 +104,27 @@ function _getImportJobsData () {
}

async function _getAppData () {
const healthInfoPath = '/health/info'
const healthInfoPath = 'health/info'

const services = [
{ name: 'Service - foreground', url: new URL(healthInfoPath, servicesConfig.serviceForeground.url) },
{ name: 'Service - background', url: new URL(healthInfoPath, servicesConfig.serviceBackground.url) },
{ name: 'Reporting', url: new URL(healthInfoPath, servicesConfig.reporting.url) },
{ name: 'Import', url: new URL(healthInfoPath, servicesConfig.import.url) },
{ name: 'Tactical CRM', url: new URL(healthInfoPath, servicesConfig.tacticalCrm.url) },
{ name: 'External UI', url: new URL(healthInfoPath, servicesConfig.externalUi.url) },
{ name: 'Internal UI', url: new URL(healthInfoPath, servicesConfig.internalUi.url) },
{ name: 'Tactical IDM', url: new URL(healthInfoPath, servicesConfig.tacticalIdm.url) },
{ name: 'Permit repository', url: new URL(healthInfoPath, servicesConfig.permitRepository.url) },
{ name: 'Returns', url: new URL(healthInfoPath, servicesConfig.returns.url) }
{ name: 'Service - foreground', serviceName: 'water' },
{ name: 'Service - background', serviceName: 'background' },
{ name: 'Reporting', serviceName: 'reporting' },
{ name: 'Import', serviceName: 'import' },
{ name: 'Tactical CRM', serviceName: 'crm' },
{ name: 'External UI', serviceName: 'external' },
{ name: 'Internal UI', serviceName: 'internal' },
{ name: 'Tactical IDM', serviceName: 'idm' },
{ name: 'Permit repository', serviceName: 'permits' },
{ name: 'Returns', serviceName: 'returns' }
]

for (const service of services) {
const result = await RequestLib.get(service.url.href)
const result = await LegacyRequestLib.get(service.serviceName, healthInfoPath, false)

if (result.succeeded) {
const data = JSON.parse(result.response.body)
service.version = data.version
service.commit = data.commit
service.version = result.response.body.version
service.commit = result.response.body.commit
service.jobs = service.name === 'Import' ? _getImportJobsData() : []
} else {
service.version = _parseFailedRequestResult(result)
Expand Down
1 change: 1 addition & 0 deletions config/services.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const config = {
password: process.env.CHARGING_MODULE_TOKEN_PASSWORD
}
},
legacyAuthToken: process.env.LEGACY_AUTH_TOKEN,
serviceForeground: {
url: process.env.SERVICE_FOREGROUND_URL
},
Expand Down
Loading