import { AvailabilityTestConfig , SerializableResponse } from 'common' ; import { IOrchestrationFunctionContext , Task , TaskSet } from 'durable-functions/lib/src/classes' ; import { TestContextData , TestEnvironment , TestGroupName } from 'functional-tests' ; import { LogLevel } from 'logger' ; import { ScanCompletedNotification , ScanRunResponse , ScanRunResultResponse } from 'service-library' ; import { PostScanRequestOptions } from 'web-api-client' ; import { ActivityAction } from '../contracts/activity-actions' ; import { ActivityRequestData , CreateScanRequestData , GetScanReportData , LogTestRunStartData , RunFunctionalTestGroupData , TestIdentifier , } from '../controllers/activity-request-data' ; import { WebApiConfig } from '../controllers/web-api-config' ; import { ActivityActionDispatcher } from './activity-action-dispatcher' ; import { OrchestrationLogger } from './orchestration-logger' ; import { ScanWaitConditions } from './scan-wait-conditions' ; import { ScanWaitOrchestrator } from './scan-wait-orchestrator' ; export class OrchestrationSteps { constructor ( private readonly context , private readonly availabilityTestConfig , private readonly logger , private readonly activityActionDispatcher , private readonly scanWaitOrchestrator , private readonly webApiConfig ) { } public getWebApiConfig ( ) { return this . webApiConfig ; } public * invokeHealthCheckRestApi ( ) { yield * this . activityActionDispatcher . callWebRequestActivity ( ActivityAction . getHealthStatus ) ; } public * invokeGetScanReportRestApi ( scanId , reportId ) { const activityName = ActivityAction . getScanReport ; const requestData = { scanId : scanId , reportId : reportId , } ; return yield * this . activityActionDispatcher . callWebRequestActivity ( activityName , requestData ) ; } public * waitForBaseScanCompletion ( scanId ) { return yield * this . scanWaitOrchestrator . waitFor ( scanId , 'waitForBaseScanCompletion' , this . availabilityTestConfig . maxScanWaitTimeInSeconds , this . availabilityTestConfig . scanWaitIntervalInSeconds , ScanWaitConditions . baseScan ) ; } public * waitForScanCompletionNotification ( scanId ) { const scanStatus = yield * this . scanWaitOrchestrator . waitFor ( scanId , 'waitForScanCompletionNotification' , this . availabilityTestConfig . maxScanCompletionNotificationWaitTimeInSeconds , this . availabilityTestConfig . scanWaitIntervalInSeconds , ScanWaitConditions . scanNotification ) ; return scanStatus ?. notification ; } public * waitForDeepScanCompletion ( scanId ) { return yield * this . scanWaitOrchestrator . waitFor ( scanId , 'waitForDeepScanCompletion' , this . availabilityTestConfig . maxDeepScanWaitTimeInSeconds , this . availabilityTestConfig . scanWaitIntervalInSeconds , ScanWaitConditions . deepScan ) ; } public * invokeSubmitScanRequestRestApi ( scanUrl , scanOptions ? ) { const requestData = { scanUrl , scanOptions : { priority : 1000 , ... scanOptions , } , } ; const response = yield * this . activityActionDispatcher . callWebRequestActivity ( ActivityAction . createScanRequest , requestData ) ; const scanId = yield * this . getScanIdFromResponse ( response , ActivityAction . createScanRequest ) ; this . logger . logOrchestrationStep ( `Orchestrator submitted scan with scan Id: ${ scanId } and options ${ JSON . stringify ( scanOptions ) }` ) ; return scanId ; } public * runFunctionalTestGroups ( testScenarioName , testContextData , testGroupNames ) { const activities = testGroupNames ?. map ( ( testGroupName ) => { const testData = { runId : this . context . df . instanceId , test : { testGroupName , scenarioName : testScenarioName , } , testContextData , environment : this . getTestEnvironment ( this . availabilityTestConfig . environmentDefinition ) , releaseId : this . webApiConfig . releaseId , } ; return { activityName : ActivityAction . runFunctionalTestGroup , data : testData , } ; } ) ; yield * this . activityActionDispatcher . callActivitiesInParallel ( activities , `Run functional tests: ${ testGroupNames }` ) ; } public * logTestRunStart ( testsToRun ) { const activityData = { runId : this . context . df . instanceId , environmentName : this . availabilityTestConfig . environmentDefinition , testsToRun : testsToRun , releaseId : this . webApiConfig . releaseId , } ; yield * this . activityActionDispatcher . callActivity ( ActivityAction . logTestRunStart , activityData ) ; } public * trackScanRequestCompleted ( ) { yield * this . activityActionDispatcher . callTrackAvailability ( true , { activityName : 'scanRequestCompleted' , } ) ; } private getTestEnvironment ( environment ) { for ( const [ key , value ] of Object . entries ( TestEnvironment ) ) { if ( key === environment ) { return value as TestEnvironment ; } } return TestEnvironment . none ; } private * getScanIdFromResponse ( response , activityName ) { const body = response . body as ScanRunResponse [ ] ; const scanRunResponse = body [ 0 ] ; if ( scanRunResponse . error !== undefined ) { this . logger . logOrchestrationStep ( 'Scan request failed' , LogLevel . error , { requestResponse : JSON . stringify ( response ) , } ) ; yield * this . activityActionDispatcher . callTrackAvailability ( false , { activityName : activityName , requestResponse : JSON . stringify ( response ) , } ) ; throw new Error ( `Request failed ${ JSON . stringify ( response ) }` ) ; } return scanRunResponse . scanId ; } }