import { Queue , StorageConfig } from 'azure-services' ; import { RetryHelper , ScanRunTimeConfig , ServiceConfiguration , System } from 'common' ; import { inject , injectable } from 'inversify' ; import { GlobalLogger } from 'logger' ; import { OnDemandPageScanRunResultProvider } from 'service-library' ; import { NotificationError , NotificationState , OnDemandNotificationRequestMessage , OnDemandPageScanResult , ScanCompletedNotification , } from 'storage-documents' ; @ injectable ( ) export class NotificationMessageDispatcher { constructor ( @ inject ( OnDemandPageScanRunResultProvider ) private readonly onDemandPageScanRunResultProvider , @ inject ( ServiceConfiguration ) private readonly serviceConfig , @ inject ( StorageConfig ) private readonly storageConfig , @ inject ( Queue ) private readonly queue , @ inject ( GlobalLogger ) private readonly logger , @ inject ( RetryHelper ) private readonly retryHelper ) { } public async sendNotificationMessage ( notificationRequestMessage ) { this . logger . setCommonProperties ( { scanId : notificationRequestMessage . scanId , } ) ; this . logger . logInfo ( `Queuing scan result notification message.` ) ; const { deepScanId , ... queueMessage } = notificationRequestMessage ; queueMessage . scanId = deepScanId ?? queueMessage . scanId ; const pageScanResult = await this . enqueueNotificationWithRetry ( queueMessage ) ; this . logger . logInfo ( `Scan result notification message successfully queued.` ) ; await this . onDemandPageScanRunResultProvider . updateScanRun ( pageScanResult ) ; } private async enqueueNotificationWithRetry ( notificationRequestMessage ) { let notificationState = 'queueFailed' ; let error = null ; const scanConfig = await this . getScanConfig ( ) ; await this . retryHelper . executeWithRetries ( async ( ) => { const response = await this . queue . createMessage ( this . storageConfig . notificationQueue , notificationRequestMessage ) ; if ( response === true ) { this . logger . logInfo ( `Notification enqueued successfully.` ) ; notificationState = 'queued' ; error = null ; } else { throw new Error ( `Queue storage encountered an error while adding a new message.` ) ; } } , async ( e ) => { this . logger . logError ( `Failed to enqueue scan result notification message. Retrying on error.` , { error : System . serializeError ( e ) , } ) ; error = { errorType : 'InternalError' , message : e . message } ; } , scanConfig . maxSendNotificationRetryCount , 1000 ) ; return { id : notificationRequestMessage . scanId , notification : this . generateNotification ( notificationRequestMessage . scanNotifyUrl , notificationState , error ) , } ; } private async getScanConfig ( ) { return this . serviceConfig . getConfigValue ( 'scanConfig' ) ; } private generateNotification ( scanNotifyUrl , state , error ) { return { scanNotifyUrl : scanNotifyUrl , state : state , error : error , } ; } }