/// <inheritdoc /> public async Task Notify(Uri uri, string resultId, string backendId, ScanResultMessage result) { var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds(5)); using var httpClient = _httpClientFactory.CreateClient(); try { var builder = new UriBuilder(uri) { Query = $"?id={resultId}" + $"&backend={backendId}" }; var response = await httpClient.PostAsync(builder.Uri, new StringContent(JsonSerializer.Serialize(result), Encoding.UTF8, "application/json"), cancellationTokenSource.Token); response.EnsureSuccessStatusCode(); _logger.LogInformation($"Sent POST to callback URL {uri}"); } catch (Exception exception) { _logger.LogError(exception, $"Failed to POST to callback URL {uri}"); } }
/// <inheritdoc /> public async Task Process(ScanQueueMessage message) { _logger.LogInformation( $"Starting scan of {message.Uri} via backend {_backend.Id} from {message.Id}"); var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds(_configuration.GetValue <int>("MAX_SCANNING_TIME"))); var cancellationToken = cancellationTokenSource.Token; var result = new ScanResultMessage { Status = ScanResultStatus.Queued }; var stopwatch = new Stopwatch(); stopwatch.Start(); try { result.Threats = await _backend.ScanAsync(message.Uri, cancellationToken); result.Status = ScanResultStatus.Succeeded; _logger.LogInformation( $"Backend {_backend.Id} completed a scan of {message.Id} " + $"with result '{string.Join(", ", result.Threats)}'"); } catch (Exception exception) { result.Status = ScanResultStatus.Failed; _logger.LogError( exception, "Scanning failed with exception"); } finally { stopwatch.Stop(); } result.Duration = stopwatch.ElapsedMilliseconds / 1000; try { _logger.LogInformation( $"Sending scan results with status {result.Status}"); _jobClient.Create <IScanResultJob>( x => x.Report(message.Id, _backend.Id, result), new EnqueuedState("default")); } catch (Exception exception) { _logger.LogError(exception, "Failed to send scan results"); } }
/// <inheritdoc /> public async Task UpdateScanResultForBackend(string resultId, string backendId, ScanResultMessage result = null) { result ??= new ScanResultMessage { Status = ScanResultStatus.Queued }; await _collection.UpdateOneAsync( Builders <ScanResult> .Filter.Where(r => r.Id == resultId), Builders <ScanResult> .Update.Set(r => r.Results[backendId], result)); }
private async Task Scan(ScanRequestMessage message) { _logger.LogInformation( $"Starting scan of {message.Uri} via backend {_backend.Id} from {message.Id}"); var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds(_configuration.GetValue <int>("MaxScanningTime"))); var result = new ScanResultMessage { Id = message.Id, Backend = _backend.Id }; var stopwatch = new Stopwatch(); stopwatch.Start(); try { result.Threats = await _backend.ScanAsync( message.Uri, cancellationTokenSource.Token); result.Succeeded = true; _logger.LogInformation( $"Backend {_backend.Id} completed a scan of {message.Id} " + $"with result '{string.Join(", ", result.Threats)}'"); } catch (Exception exception) { result.Succeeded = false; _logger.LogError( exception, "Scanning failed with exception"); } finally { stopwatch.Stop(); } result.Duration = stopwatch.ElapsedMilliseconds / 1000; _logger.LogInformation( $"Sending scan results with status {result.Succeeded}"); await _bus.SendAsync( _configuration.GetValue <string>("ResultsSubscriptionId"), result); }
/// <inheritdoc /> public async Task Report(string resultId, string backendId, ScanResultMessage result) { _logger.LogInformation( $"Received a result from {backendId} for {result} with status {result.Status} " + $"and threats {string.Join(",", result.Threats)}"); await _scanResultService.UpdateScanResultForBackend(resultId, backendId, result); var scanResult = await _scanResultService.GetScanResult(resultId); if (scanResult?.CallbackUrl == null) { return; } _backgroundJobClient.Create <IScanResultJob>( x => x.Notify(scanResult.CallbackUrl, resultId, backendId, result), new EnqueuedState("default")); }
private async Task StoreScanResult(ScanResultMessage message) { message.Threats ??= new string[] { }; _logger.LogInformation( $"Received a result from {message.Backend} for {message.Id} " + $"with threats {string.Join(",", message.Threats)}"); await _scanResultService.UpdateScanResultForBackend( message.Id, message.Backend, message.Duration, true, message.Succeeded, message.Threats); var result = await _scanResultService.GetScanResult(message.Id); if (result?.CallbackUrl == null) { return; } var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds(3)); using var httpClient = _httpClientFactory.CreateClient(); try { var response = await httpClient.PostAsync( result.CallbackUrl, new StringContent(JsonConvert.SerializeObject(result), Encoding.UTF8, "application/json"), cancellationTokenSource.Token); response.EnsureSuccessStatusCode(); } catch (Exception exception) { _logger.LogError(exception, $"Failed to POST to callback URL {result.CallbackUrl}"); } }