import { getForeverAgents , ResponseWithBodyType , RetryHelper , System } from 'common' ; import got , { Agents , ExtendOptions , Got , Options } from 'got' ; import { injectable } from 'inversify' ; import { Logger } from 'logger' ; import { HealthReport , ScanResultResponse , ScanRunRequest , ScanRunResponse } from 'service-library' ; import { A11yServiceCredential } from './a11y-service-credential' ; import { PostScanRequestOptions } from './request-options' ; @ injectable ( ) export class A11yServiceClient { private readonly defaultRequestObject : Got ; private readonly defaultOptions : ExtendOptions = { searchParams : { 'api-version' : this . apiVersion , } , headers : { 'Content-Type' : 'application/json' , } , responseType : 'json' , } ; constructor ( private readonly credential , private readonly requestBaseUrl , private readonly logger , private readonly apiVersion = '1.0' , throwOnRequestFailure = false , request = got , private readonly retryHelper = new RetryHelper ( ) , private readonly maxRetryCount = 5 , private readonly msecBetweenRetries = 1000 , getAgentsFn = getForeverAgents ) { this . defaultRequestObject = request . extend ( { ... this . defaultOptions , throwHttpErrors : throwOnRequestFailure , agent : getAgentsFn ( ) , } ) ; } public async postScanUrl ( scanUrl , options ? ) { const scanRequestData = { url : scanUrl , scanNotifyUrl : options ?. scanNotificationUrl , priority : options ?. priority || 0 , deepScan : options ?. deepScan , } ; if ( options ?. consolidatedId ) { scanRequestData . reportGroups = [ { consolidatedId : options . consolidatedId } ] ; scanRequestData . site = { baseUrl : scanUrl , ... options . deepScanOptions , } ; } return this . postScanUrlWithRequest ( scanRequestData ) ; } private async postScanUrlWithRequest ( scanRequestData ) { const requestUrl = `${ this . requestBaseUrl }/scans` ; const options = { json : [ scanRequestData ] } ; return ( await this . retryHelper . executeWithRetries ( async ( ) => ( await this . signRequest ( ) ) . post ( requestUrl , options ) , async ( e ) => this . logger . logError ( 'POST scans REST API request fail. Retrying on error.' , { url : requestUrl , error : System . serializeError ( e ) , } ) , this . maxRetryCount , this . msecBetweenRetries ) ) as ResponseWithBodyType < ScanRunResponse [ ] > ; } public async getScanStatus ( scanId ) { const requestUrl = `${ this . requestBaseUrl }/scans/${ scanId }` ; return ( await this . retryHelper . executeWithRetries ( async ( ) => ( await this . signRequest ( ) ) . get ( requestUrl ) , async ( e ) => this . logger . logError ( 'GET scan result REST API request fail. Retrying on error.' , { url : requestUrl , error : System . serializeError ( e ) , } ) , this . maxRetryCount , this . msecBetweenRetries ) ) as ResponseWithBodyType < ScanResultResponse > ; } public async getScanReport ( scanId , reportId ) { const requestUrl = `${ this . requestBaseUrl }/scans/${ scanId }/reports/${ reportId }` ; return ( await this . retryHelper . executeWithRetries ( async ( ) => ( await this . signRequest ( ) ) . get ( requestUrl , { responseType : 'text' } ) , async ( e ) => this . logger . logError ( 'GET scan report REST API request fail. Retrying on error.' , { url : requestUrl , error : System . serializeError ( e ) , } ) , this . maxRetryCount , this . msecBetweenRetries ) ) as ResponseWithBodyType < Buffer > ; } public async checkHealth ( urlSuffix = '' ) { const requestUrl = `${ this . requestBaseUrl }/health${ urlSuffix }` ; return ( await this . retryHelper . executeWithRetries ( async ( ) => ( await this . signRequest ( ) ) . get ( requestUrl ) , async ( e ) => this . logger . logError ( 'GET health status REST API request fail. Retrying on error.' , { url : requestUrl , error : System . serializeError ( e ) , } ) , this . maxRetryCount , this . msecBetweenRetries ) ) as ResponseWithBodyType < HealthReport > ; } private async signRequest ( ) { return this . credential . signRequest ( this . defaultRequestObject ) ; } }