2020-11-02 11:00:24 +02:00

94 lines
3.4 KiB
C#

using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Hangfire;
using Hangfire.States;
using MalwareMultiScan.Api.Services.Interfaces;
using MalwareMultiScan.Shared.Message;
using MalwareMultiScan.Shared.Services.Interfaces;
using Microsoft.Extensions.Logging;
namespace MalwareMultiScan.Api.Services
{
/// <summary>
/// Job for storing scan results.
/// </summary>
public class ScanResultJob : IScanResultJob
{
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<ScanResultJob> _logger;
private readonly IScanResultService _scanResultService;
/// <summary>
/// Initialize scan result storing job.
/// </summary>
/// <param name="logger">Logger.</param>
/// <param name="httpClientFactory">HTTP client factory.</param>
/// <param name="scanResultService">Scan result service.</param>
/// <param name="backgroundJobClient">Background job client.</param>
public ScanResultJob(
ILogger<ScanResultJob> logger,
IHttpClientFactory httpClientFactory,
IScanResultService scanResultService,
IBackgroundJobClient backgroundJobClient)
{
_logger = logger;
_httpClientFactory = httpClientFactory;
_scanResultService = scanResultService;
_backgroundJobClient = backgroundJobClient;
}
/// <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"));
}
/// <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}");
}
}
}
}