using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using EasyNetQ; using MalwareMultiScan.Backends.Interfaces; using MalwareMultiScan.Backends.Messages; using MalwareMultiScan.Scanner.Services.Interfaces; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace MalwareMultiScan.Scanner.Services.Implementations { /// public class ScanHostedService : IScanHostedService { private readonly IScanBackend _backend; private readonly IBus _bus; private readonly IConfiguration _configuration; private readonly ILogger _logger; /// /// Initialise scan hosted service. /// /// Logger. /// Scan backend. /// EasyNetQ bus. /// Configuration. public ScanHostedService( ILogger logger, IScanBackend backend, IBus bus, IConfiguration configuration) { _logger = logger; _bus = bus; _configuration = configuration; _backend = backend; } /// public Task StartAsync(CancellationToken cancellationToken) { _bus.Receive(_backend.Id, Scan); _logger.LogInformation( $"Started scan hosting service for the backend {_backend.Id}"); return Task.CompletedTask; } /// public Task StopAsync(CancellationToken cancellationToken) { _bus.Dispose(); _logger.LogInformation( $"Stopped scan hosting service for the backend {_backend.Id}"); return Task.CompletedTask; } 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("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("ResultsSubscriptionId"), result); } } }