using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Hangfire; using Hangfire.States; using MalwareMultiScan.Backends.Backends.Interfaces; using MalwareMultiScan.Shared.Enums; using MalwareMultiScan.Shared.Message; using MalwareMultiScan.Shared.Services.Interfaces; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace MalwareMultiScan.ScannerWorker.Services { /// public class ScanBackgroundJob : IScanBackgroundJob { private readonly IScanBackend _backend; private readonly IConfiguration _configuration; private readonly IBackgroundJobClient _jobClient; private readonly ILogger _logger; /// /// Initialize scan background job. /// /// Configuration. /// Logger. /// Scan backend. /// public ScanBackgroundJob( IScanBackend backend, IConfiguration configuration, ILogger logger, IBackgroundJobClient jobClient) { _backend = backend; _configuration = configuration; _logger = logger; _jobClient = jobClient; } /// 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("MAX_SCANNING_TIME"))); var cancellationToken = cancellationTokenSource.Token; var result = new ScanResultMessage(); 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( x => x.Report(message.Id, _backend.Id, result), new EnqueuedState()); } catch (Exception exception) { _logger.LogError(exception, "Failed to send scan results"); } } } }