diff --git a/code/Executable/DependencyInjection/MainDI.cs b/code/Executable/DependencyInjection/MainDI.cs index 2bb12588..078a9a35 100644 --- a/code/Executable/DependencyInjection/MainDI.cs +++ b/code/Executable/DependencyInjection/MainDI.cs @@ -1,8 +1,6 @@ using System.Net; -using Castle.DynamicProxy; using Common.Configuration.General; using Common.Helpers; -using Infrastructure.Interceptors; using Infrastructure.Verticals.DownloadClient.Deluge; using Infrastructure.Verticals.Notifications.Consumers; using Infrastructure.Verticals.Notifications.Models; @@ -42,8 +40,7 @@ public static class MainDI e.PrefetchCount = 1; }); }); - }) - .AddDryRunInterceptor(); + }); private static IServiceCollection AddHttpClients(this IServiceCollection services, IConfiguration configuration) { @@ -91,31 +88,4 @@ public static class MainDI .OrResult(response => !response.IsSuccessStatusCode && response.StatusCode != HttpStatusCode.Unauthorized) .WaitAndRetryAsync(config.MaxRetries, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))) ); - - private static IServiceCollection AddDryRunInterceptor(this IServiceCollection services) - { - services - .Where(s => s.ServiceType != typeof(IDryRunService) && typeof(IDryRunService).IsAssignableFrom(s.ServiceType)) - .ToList() - .ForEach(service => - { - services.Decorate(service.ServiceType, (target, svc) => - { - ProxyGenerator proxyGenerator = new(); - DryRunAsyncInterceptor interceptor = svc.GetRequiredService(); - - object implementation = proxyGenerator.CreateClassProxyWithTarget( - service.ServiceType, - target, - interceptor - ); - - ((IInterceptedService)target).Proxy = implementation; - - return implementation; - }); - }); - - return services; - } } \ No newline at end of file diff --git a/code/Executable/DependencyInjection/NotificationsDI.cs b/code/Executable/DependencyInjection/NotificationsDI.cs index 87bf3852..df9961b1 100644 --- a/code/Executable/DependencyInjection/NotificationsDI.cs +++ b/code/Executable/DependencyInjection/NotificationsDI.cs @@ -10,7 +10,7 @@ public static class NotificationsDI .Configure(configuration.GetSection(NotifiarrConfig.SectionName)) .AddTransient() .AddTransient() - .AddTransient() + .AddTransient() .AddTransient() .AddTransient(); } \ No newline at end of file diff --git a/code/Executable/DependencyInjection/ServicesDI.cs b/code/Executable/DependencyInjection/ServicesDI.cs index b1730228..e1becadb 100644 --- a/code/Executable/DependencyInjection/ServicesDI.cs +++ b/code/Executable/DependencyInjection/ServicesDI.cs @@ -15,7 +15,7 @@ public static class ServicesDI { public static IServiceCollection AddServices(this IServiceCollection services) => services - .AddTransient() + .AddTransient() .AddTransient() .AddTransient() .AddTransient() diff --git a/code/Infrastructure.Tests/Verticals/DownloadClient/DownloadServiceFixture.cs b/code/Infrastructure.Tests/Verticals/DownloadClient/DownloadServiceFixture.cs index bdab1877..e1d35596 100644 --- a/code/Infrastructure.Tests/Verticals/DownloadClient/DownloadServiceFixture.cs +++ b/code/Infrastructure.Tests/Verticals/DownloadClient/DownloadServiceFixture.cs @@ -1,6 +1,7 @@ using Common.Configuration.ContentBlocker; using Common.Configuration.DownloadCleaner; using Common.Configuration.QueueCleaner; +using Infrastructure.Interceptors; using Infrastructure.Verticals.ContentBlocker; using Infrastructure.Verticals.DownloadClient; using Infrastructure.Verticals.ItemStriker; @@ -53,7 +54,8 @@ public class DownloadServiceFixture : IDisposable downloadCleanerOptions.Value.Returns(new DownloadCleanerConfig()); var filenameEvaluator = Substitute.For(); - var notifier = Substitute.For(); + var notifier = Substitute.For(); + var dryRunInterceptor = Substitute.For(); return new TestDownloadService( Logger, @@ -63,7 +65,8 @@ public class DownloadServiceFixture : IDisposable Cache, filenameEvaluator, Striker, - notifier + notifier, + dryRunInterceptor ); } diff --git a/code/Infrastructure.Tests/Verticals/DownloadClient/TestDownloadService.cs b/code/Infrastructure.Tests/Verticals/DownloadClient/TestDownloadService.cs index 022f113c..abf0f765 100644 --- a/code/Infrastructure.Tests/Verticals/DownloadClient/TestDownloadService.cs +++ b/code/Infrastructure.Tests/Verticals/DownloadClient/TestDownloadService.cs @@ -3,6 +3,7 @@ using System.Text.RegularExpressions; using Common.Configuration.ContentBlocker; using Common.Configuration.DownloadCleaner; using Common.Configuration.QueueCleaner; +using Infrastructure.Interceptors; using Infrastructure.Verticals.ContentBlocker; using Infrastructure.Verticals.DownloadClient; using Infrastructure.Verticals.ItemStriker; @@ -23,9 +24,12 @@ public class TestDownloadService : DownloadService IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, - NotificationPublisher notifier) - : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, - cache, filenameEvaluator, striker, notifier) + INotificationPublisher notifier, + IDryRunInterceptor dryRunInterceptor + ) : base( + logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, + filenameEvaluator, striker, notifier, dryRunInterceptor + ) { } diff --git a/code/Infrastructure/Infrastructure.csproj b/code/Infrastructure/Infrastructure.csproj index 09e6876b..ad0c2da3 100644 --- a/code/Infrastructure/Infrastructure.csproj +++ b/code/Infrastructure/Infrastructure.csproj @@ -12,7 +12,6 @@ - diff --git a/code/Infrastructure/Interceptors/DryRunInterceptor.cs b/code/Infrastructure/Interceptors/DryRunInterceptor.cs index df632ea6..2c1b3225 100644 --- a/code/Infrastructure/Interceptors/DryRunInterceptor.cs +++ b/code/Infrastructure/Interceptors/DryRunInterceptor.cs @@ -1,5 +1,4 @@ using System.Reflection; -using Castle.DynamicProxy; using Common.Attributes; using Common.Configuration.General; using Microsoft.Extensions.Logging; @@ -7,41 +6,70 @@ using Microsoft.Extensions.Options; namespace Infrastructure.Interceptors; -public class DryRunAsyncInterceptor : AsyncInterceptorBase +public class DryRunInterceptor : IDryRunInterceptor { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly DryRunConfig _config; - public DryRunAsyncInterceptor(ILogger logger, IOptions config) + public DryRunInterceptor(ILogger logger, IOptions config) { _logger = logger; _config = config.Value; } - protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func proceed) + public void Intercept(Action action) { - MethodInfo? method = invocation.MethodInvocationTarget ?? invocation.Method; - if (IsDryRun(method)) + MethodInfo methodInfo = action.Method; + + if (IsDryRun(methodInfo)) { - _logger.LogInformation("[DRY RUN] skipping method: {name}", method.Name); + _logger.LogInformation("[DRY RUN] skipping method: {name}", methodInfo.Name); return; } - await proceed(invocation, proceedInfo); + action(); } - - protected override async Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func> proceed) + + public Task InterceptAsync(Delegate action, params object[] parameters) { - MethodInfo? method = invocation.MethodInvocationTarget ?? invocation.Method; - if (IsDryRun(method)) + MethodInfo methodInfo = action.Method; + + if (IsDryRun(methodInfo)) { - _logger.LogInformation("[DRY RUN] skipping method: {name}", method.Name); - return default!; + _logger.LogInformation("[DRY RUN] skipping method: {name}", methodInfo.Name); + return Task.CompletedTask; } - return await proceed(invocation, proceedInfo); - } + object? result = action.DynamicInvoke(parameters); + if (result is Task task) + { + return task; + } + + return Task.CompletedTask; + } + + public Task InterceptAsync(Delegate action, params object[] parameters) + { + MethodInfo methodInfo = action.Method; + + if (IsDryRun(methodInfo)) + { + _logger.LogInformation("[DRY RUN] skipping method: {name}", methodInfo.Name); + return Task.FromResult(default(T)); + } + + object? result = action.DynamicInvoke(parameters); + + if (result is Task task) + { + return task; + } + + return Task.FromResult(default(T)); + } + private bool IsDryRun(MethodInfo method) { return method.GetCustomAttributes(typeof(DryRunSafeguardAttribute), true).Any() && _config.IsDryRun; diff --git a/code/Infrastructure/Interceptors/IDryRunInterceptor.cs b/code/Infrastructure/Interceptors/IDryRunInterceptor.cs new file mode 100644 index 00000000..2602e06e --- /dev/null +++ b/code/Infrastructure/Interceptors/IDryRunInterceptor.cs @@ -0,0 +1,10 @@ +namespace Infrastructure.Interceptors; + +public interface IDryRunInterceptor +{ + void Intercept(Action action); + + Task InterceptAsync(Delegate action, params object[] parameters); + + Task InterceptAsync(Delegate action, params object[] parameters); +} \ No newline at end of file diff --git a/code/Infrastructure/Interceptors/IDryRunService.cs b/code/Infrastructure/Interceptors/IDryRunService.cs deleted file mode 100644 index 003d1b67..00000000 --- a/code/Infrastructure/Interceptors/IDryRunService.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Infrastructure.Interceptors; - -public interface IDryRunService : IInterceptedService -{ -} \ No newline at end of file diff --git a/code/Infrastructure/Interceptors/IInterceptedService.cs b/code/Infrastructure/Interceptors/IInterceptedService.cs deleted file mode 100644 index 3d70429a..00000000 --- a/code/Infrastructure/Interceptors/IInterceptedService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Infrastructure.Interceptors; - -public interface IInterceptedService -{ - public object Proxy { get; set; } -} \ No newline at end of file diff --git a/code/Infrastructure/Interceptors/InterceptedService.cs b/code/Infrastructure/Interceptors/InterceptedService.cs deleted file mode 100644 index af92f8df..00000000 --- a/code/Infrastructure/Interceptors/InterceptedService.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Infrastructure.Interceptors; - -public class InterceptedService : IInterceptedService -{ - private object? _proxy; - - public object Proxy - { - get - { - if (_proxy is null) - { - throw new Exception("Proxy is not set"); - } - - return _proxy; - } - - set => _proxy = value; - } -} \ No newline at end of file diff --git a/code/Infrastructure/Verticals/Arr/ArrClient.cs b/code/Infrastructure/Verticals/Arr/ArrClient.cs index 3a1ee1b9..2af6d02d 100644 --- a/code/Infrastructure/Verticals/Arr/ArrClient.cs +++ b/code/Infrastructure/Verticals/Arr/ArrClient.cs @@ -15,27 +15,22 @@ using Newtonsoft.Json; namespace Infrastructure.Verticals.Arr; -public abstract class ArrClient : InterceptedService, IArrClient, IDryRunService +public abstract class ArrClient : IArrClient { protected readonly ILogger _logger; protected readonly HttpClient _httpClient; protected readonly LoggingConfig _loggingConfig; protected readonly QueueCleanerConfig _queueCleanerConfig; protected readonly IStriker _striker; - - /// - /// Constructor to be used by interceptors. - /// - protected ArrClient() - { - } + protected readonly IDryRunInterceptor _dryRunInterceptor; protected ArrClient( ILogger logger, IHttpClientFactory httpClientFactory, IOptions loggingConfig, IOptions queueCleanerConfig, - IStriker striker + IStriker striker, + IDryRunInterceptor dryRunInterceptor ) { _logger = logger; @@ -43,6 +38,7 @@ public abstract class ArrClient : InterceptedService, IArrClient, IDryRunService _loggingConfig = loggingConfig.Value; _queueCleanerConfig = queueCleanerConfig.Value; _striker = striker; + _dryRunInterceptor = dryRunInterceptor; } public virtual async Task GetQueueItemsAsync(ArrInstance arrInstance, int page) @@ -125,7 +121,8 @@ public abstract class ArrClient : InterceptedService, IArrClient, IDryRunService using HttpRequestMessage request = new(HttpMethod.Delete, uri); SetApiKey(request, arrInstance.ApiKey); - using var _ = await ((ArrClient)Proxy).SendRequestAsync(request); + HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync(SendRequestAsync, request); + response?.Dispose(); _logger.LogInformation( removeFromClient diff --git a/code/Infrastructure/Verticals/Arr/LidarrClient.cs b/code/Infrastructure/Verticals/Arr/LidarrClient.cs index fb8171f6..08ee3f7f 100644 --- a/code/Infrastructure/Verticals/Arr/LidarrClient.cs +++ b/code/Infrastructure/Verticals/Arr/LidarrClient.cs @@ -5,6 +5,7 @@ using Common.Configuration.QueueCleaner; using Domain.Models.Arr; using Domain.Models.Arr.Queue; using Domain.Models.Lidarr; +using Infrastructure.Interceptors; using Infrastructure.Verticals.Arr.Interfaces; using Infrastructure.Verticals.ItemStriker; using Microsoft.Extensions.Logging; @@ -15,18 +16,14 @@ namespace Infrastructure.Verticals.Arr; public class LidarrClient : ArrClient, ILidarrClient { - /// - public LidarrClient() - { - } - public LidarrClient( ILogger logger, IHttpClientFactory httpClientFactory, IOptions loggingConfig, IOptions queueCleanerConfig, - IStriker striker - ) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker) + IStriker striker, + IDryRunInterceptor dryRunInterceptor + ) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker, dryRunInterceptor) { } @@ -64,7 +61,8 @@ public class LidarrClient : ArrClient, ILidarrClient try { - using var _ = await ((LidarrClient)Proxy).SendRequestAsync(request); + HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync(SendRequestAsync, request); + response?.Dispose(); _logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext)); } diff --git a/code/Infrastructure/Verticals/Arr/RadarrClient.cs b/code/Infrastructure/Verticals/Arr/RadarrClient.cs index e0e31925..86add323 100644 --- a/code/Infrastructure/Verticals/Arr/RadarrClient.cs +++ b/code/Infrastructure/Verticals/Arr/RadarrClient.cs @@ -5,6 +5,7 @@ using Common.Configuration.QueueCleaner; using Domain.Models.Arr; using Domain.Models.Arr.Queue; using Domain.Models.Radarr; +using Infrastructure.Interceptors; using Infrastructure.Verticals.Arr.Interfaces; using Infrastructure.Verticals.ItemStriker; using Microsoft.Extensions.Logging; @@ -15,18 +16,14 @@ namespace Infrastructure.Verticals.Arr; public class RadarrClient : ArrClient, IRadarrClient { - /// - public RadarrClient() - { - } - public RadarrClient( ILogger logger, IHttpClientFactory httpClientFactory, IOptions loggingConfig, IOptions queueCleanerConfig, - IStriker striker - ) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker) + IStriker striker, + IDryRunInterceptor dryRunInterceptor + ) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker, dryRunInterceptor) { } @@ -72,7 +69,8 @@ public class RadarrClient : ArrClient, IRadarrClient try { - using var _ = await ((RadarrClient)Proxy).SendRequestAsync(request); + HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync(SendRequestAsync, request); + response?.Dispose(); _logger.LogInformation("{log}", GetSearchLog(arrInstance.Url, command, true, logContext)); } diff --git a/code/Infrastructure/Verticals/Arr/SonarrClient.cs b/code/Infrastructure/Verticals/Arr/SonarrClient.cs index 93156696..bfba28a1 100644 --- a/code/Infrastructure/Verticals/Arr/SonarrClient.cs +++ b/code/Infrastructure/Verticals/Arr/SonarrClient.cs @@ -5,6 +5,7 @@ using Common.Configuration.QueueCleaner; using Domain.Models.Arr; using Domain.Models.Arr.Queue; using Domain.Models.Sonarr; +using Infrastructure.Interceptors; using Infrastructure.Verticals.Arr.Interfaces; using Infrastructure.Verticals.ItemStriker; using Microsoft.Extensions.Logging; @@ -16,18 +17,14 @@ namespace Infrastructure.Verticals.Arr; public class SonarrClient : ArrClient, ISonarrClient { - /// - public SonarrClient() - { - } - public SonarrClient( ILogger logger, IHttpClientFactory httpClientFactory, IOptions loggingConfig, IOptions queueCleanerConfig, - IStriker striker - ) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker) + IStriker striker, + IDryRunInterceptor dryRunInterceptor + ) : base(logger, httpClientFactory, loggingConfig, queueCleanerConfig, striker, dryRunInterceptor) { } @@ -68,8 +65,9 @@ public class SonarrClient : ArrClient, ISonarrClient try { - using var _ = await ((SonarrClient)Proxy).SendRequestAsync(request); - + HttpResponseMessage? response = await _dryRunInterceptor.InterceptAsync(SendRequestAsync, request); + response?.Dispose(); + _logger.LogInformation("{log}", GetSearchLog(command.SearchType, arrInstance.Url, command, true, logContext)); } catch diff --git a/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs b/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs index 8f6284b5..7eff7185 100644 --- a/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs +++ b/code/Infrastructure/Verticals/ContentBlocker/ContentBlocker.cs @@ -36,7 +36,7 @@ public sealed class ContentBlocker : GenericHandler ArrQueueIterator arrArrQueueIterator, BlocklistProvider blocklistProvider, DownloadServiceFactory downloadServiceFactory, - NotificationPublisher notifier + INotificationPublisher notifier ) : base( logger, downloadClientConfig, sonarrConfig, radarrConfig, lidarrConfig, diff --git a/code/Infrastructure/Verticals/DownloadCleaner/DownloadCleaner.cs b/code/Infrastructure/Verticals/DownloadCleaner/DownloadCleaner.cs index 27b3a566..d18938b9 100644 --- a/code/Infrastructure/Verticals/DownloadCleaner/DownloadCleaner.cs +++ b/code/Infrastructure/Verticals/DownloadCleaner/DownloadCleaner.cs @@ -31,7 +31,7 @@ public sealed class DownloadCleaner : GenericHandler LidarrClient lidarrClient, ArrQueueIterator arrArrQueueIterator, DownloadServiceFactory downloadServiceFactory, - NotificationPublisher notifier + INotificationPublisher notifier ) : base( logger, downloadClientConfig, sonarrConfig, radarrConfig, lidarrConfig, diff --git a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs index 58924608..47cfc3fe 100644 --- a/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/Deluge/DelugeService.cs @@ -7,11 +7,11 @@ using Common.Configuration.DownloadClient; using Common.Configuration.QueueCleaner; using Domain.Enums; using Domain.Models.Deluge.Response; +using Infrastructure.Interceptors; using Infrastructure.Verticals.ContentBlocker; using Infrastructure.Verticals.Context; using Infrastructure.Verticals.ItemStriker; using Infrastructure.Verticals.Notifications; -using MassTransit.Configuration; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -22,11 +22,6 @@ public class DelugeService : DownloadService, IDelugeService { private readonly DelugeClient _client; - /// - public DelugeService() - { - } - public DelugeService( ILogger logger, IOptions config, @@ -37,8 +32,12 @@ public class DelugeService : DownloadService, IDelugeService IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, - NotificationPublisher notifier - ) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier) + INotificationPublisher notifier, + IDryRunInterceptor dryRunInterceptor + ) : base( + logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, + filenameEvaluator, striker, notifier, dryRunInterceptor + ) { config.Value.Validate(); _client = new (config, httpClientFactory); @@ -190,7 +189,7 @@ public class DelugeService : DownloadService, IDelugeService return result; } - await ((DelugeService)Proxy).ChangeFilesPriority(hash, sortedPriorities); + await _dryRunInterceptor.InterceptAsync(ChangeFilesPriority, hash, sortedPriorities); return result; } @@ -245,8 +244,8 @@ public class DelugeService : DownloadService, IDelugeService { continue; } - - await ((DelugeService)Proxy).DeleteDownload(download.Hash); + + await _dryRunInterceptor.InterceptAsync(DeleteDownload, download.Hash); _logger.LogInformation( "download cleaned | {reason} reached | {name}", diff --git a/code/Infrastructure/Verticals/DownloadClient/DownloadService.cs b/code/Infrastructure/Verticals/DownloadClient/DownloadService.cs index e32ed70b..3f528d38 100644 --- a/code/Infrastructure/Verticals/DownloadClient/DownloadService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/DownloadService.cs @@ -18,7 +18,7 @@ using Microsoft.Extensions.Options; namespace Infrastructure.Verticals.DownloadClient; -public abstract class DownloadService : InterceptedService, IDownloadService +public abstract class DownloadService : IDownloadService { protected readonly ILogger _logger; protected readonly QueueCleanerConfig _queueCleanerConfig; @@ -28,15 +28,9 @@ public abstract class DownloadService : InterceptedService, IDownloadService protected readonly IFilenameEvaluator _filenameEvaluator; protected readonly IStriker _striker; protected readonly MemoryCacheEntryOptions _cacheOptions; - protected readonly NotificationPublisher _notifier; + protected readonly INotificationPublisher _notifier; + protected readonly IDryRunInterceptor _dryRunInterceptor; - /// - /// Constructor to be used by interceptors. - /// - protected DownloadService() - { - } - protected DownloadService( ILogger logger, IOptions queueCleanerConfig, @@ -45,7 +39,9 @@ public abstract class DownloadService : InterceptedService, IDownloadService IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, - NotificationPublisher notifier) + INotificationPublisher notifier, + IDryRunInterceptor dryRunInterceptor + ) { _logger = logger; _queueCleanerConfig = queueCleanerConfig.Value; @@ -55,6 +51,7 @@ public abstract class DownloadService : InterceptedService, IDownloadService _filenameEvaluator = filenameEvaluator; _striker = striker; _notifier = notifier; + _dryRunInterceptor = dryRunInterceptor; _cacheOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(StaticConfiguration.TriggerValue + Constants.CacheLimitBuffer); } diff --git a/code/Infrastructure/Verticals/DownloadClient/DummyDownloadService.cs b/code/Infrastructure/Verticals/DownloadClient/DummyDownloadService.cs index f3c78e90..91263283 100644 --- a/code/Infrastructure/Verticals/DownloadClient/DummyDownloadService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/DummyDownloadService.cs @@ -3,6 +3,7 @@ using System.Text.RegularExpressions; using Common.Configuration.ContentBlocker; using Common.Configuration.DownloadCleaner; using Common.Configuration.QueueCleaner; +using Infrastructure.Interceptors; using Infrastructure.Verticals.ContentBlocker; using Infrastructure.Verticals.ItemStriker; using Infrastructure.Verticals.Notifications; @@ -14,12 +15,7 @@ namespace Infrastructure.Verticals.DownloadClient; public class DummyDownloadService : DownloadService { - /// - public DummyDownloadService() - { - } - - public DummyDownloadService(ILogger logger, IOptions queueCleanerConfig, IOptions contentBlockerConfig, IOptions downloadCleanerConfig, IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, NotificationPublisher notifier) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier) + public DummyDownloadService(ILogger logger, IOptions queueCleanerConfig, IOptions contentBlockerConfig, IOptions downloadCleanerConfig, IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, INotificationPublisher notifier, IDryRunInterceptor dryRunInterceptor) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier, dryRunInterceptor) { } diff --git a/code/Infrastructure/Verticals/DownloadClient/IDownloadService.cs b/code/Infrastructure/Verticals/DownloadClient/IDownloadService.cs index d5975e8d..c2d446fc 100644 --- a/code/Infrastructure/Verticals/DownloadClient/IDownloadService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/IDownloadService.cs @@ -6,7 +6,7 @@ using Infrastructure.Interceptors; namespace Infrastructure.Verticals.DownloadClient; -public interface IDownloadService : IDisposable, IDryRunService +public interface IDownloadService : IDisposable { public Task LoginAsync(); diff --git a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/IQBitService.cs b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/IQBitService.cs index fa89196d..2f7a14bc 100644 --- a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/IQBitService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/IQBitService.cs @@ -1,5 +1,5 @@ namespace Infrastructure.Verticals.DownloadClient.QBittorrent; -public interface IQBitService : IDownloadService +public interface IQBitService : IDownloadService, IDisposable { } \ No newline at end of file diff --git a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs index fe8d6d82..0e14776a 100644 --- a/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/QBittorrent/QBitService.cs @@ -7,6 +7,7 @@ using Common.Configuration.DownloadClient; using Common.Configuration.QueueCleaner; using Common.Helpers; using Domain.Enums; +using Infrastructure.Interceptors; using Infrastructure.Verticals.ContentBlocker; using Infrastructure.Verticals.Context; using Infrastructure.Verticals.ItemStriker; @@ -24,11 +25,6 @@ public class QBitService : DownloadService, IQBitService private readonly QBitConfig _config; private readonly QBittorrentClient _client; - /// - public QBitService() - { - } - public QBitService( ILogger logger, IHttpClientFactory httpClientFactory, @@ -39,8 +35,12 @@ public class QBitService : DownloadService, IQBitService IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, - NotificationPublisher notifier - ) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier) + INotificationPublisher notifier, + IDryRunInterceptor dryRunInterceptor + ) : base( + logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, + filenameEvaluator, striker, notifier, dryRunInterceptor + ) { _config = config.Value; _config.Validate(); @@ -200,7 +200,7 @@ public class QBitService : DownloadService, IQBitService foreach (int fileIndex in unwantedFiles) { - await ((QBitService)Proxy).SkipFile(hash, fileIndex); + await _dryRunInterceptor.InterceptAsync(SkipFile, hash, fileIndex); } return result; @@ -272,7 +272,7 @@ public class QBitService : DownloadService, IQBitService continue; } - await ((QBitService)Proxy).DeleteDownload(download.Hash); + await _dryRunInterceptor.InterceptAsync(DeleteDownload, download.Hash); _logger.LogInformation( "download cleaned | {reason} reached | {name}", diff --git a/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs b/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs index 4479f384..80abfa79 100644 --- a/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs +++ b/code/Infrastructure/Verticals/DownloadClient/Transmission/TransmissionService.cs @@ -7,6 +7,7 @@ using Common.Configuration.DownloadClient; using Common.Configuration.QueueCleaner; using Common.Helpers; using Domain.Enums; +using Infrastructure.Interceptors; using Infrastructure.Verticals.ContentBlocker; using Infrastructure.Verticals.Context; using Infrastructure.Verticals.ItemStriker; @@ -26,11 +27,6 @@ public class TransmissionService : DownloadService, ITransmissionService private readonly Client _client; private TorrentInfo[]? _torrentsCache; - /// - public TransmissionService() - { - } - public TransmissionService( IHttpClientFactory httpClientFactory, ILogger logger, @@ -41,8 +37,12 @@ public class TransmissionService : DownloadService, ITransmissionService IMemoryCache cache, IFilenameEvaluator filenameEvaluator, IStriker striker, - NotificationPublisher notifier - ) : base(logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, filenameEvaluator, striker, notifier) + INotificationPublisher notifier, + IDryRunInterceptor dryRunInterceptor + ) : base( + logger, queueCleanerConfig, contentBlockerConfig, downloadCleanerConfig, cache, + filenameEvaluator, striker, notifier, dryRunInterceptor + ) { _config = config.Value; _config.Validate(); @@ -174,8 +174,8 @@ public class TransmissionService : DownloadService, ITransmissionService } _logger.LogDebug("changing priorities | torrent {hash}", hash); - - await ((TransmissionService)Proxy).SetUnwantedFiles(torrent.Id, unwantedFiles.ToArray()); + + await _dryRunInterceptor.InterceptAsync(SetUnwantedFiles, torrent.Id, unwantedFiles.ToArray()); return result; } @@ -268,7 +268,7 @@ public class TransmissionService : DownloadService, ITransmissionService continue; } - await ((TransmissionService)Proxy).RemoveDownloadAsync(download.Id); + await _dryRunInterceptor.InterceptAsync(RemoveDownloadAsync, download.Id); _logger.LogInformation( "download cleaned | {reason} reached | {name}", diff --git a/code/Infrastructure/Verticals/ItemStriker/Striker.cs b/code/Infrastructure/Verticals/ItemStriker/Striker.cs index 84f8b29d..04e5bdcf 100644 --- a/code/Infrastructure/Verticals/ItemStriker/Striker.cs +++ b/code/Infrastructure/Verticals/ItemStriker/Striker.cs @@ -1,6 +1,7 @@ using Common.Helpers; using Domain.Enums; using Infrastructure.Helpers; +using Infrastructure.Interceptors; using Infrastructure.Verticals.Context; using Infrastructure.Verticals.Notifications; using Microsoft.Extensions.Caching.Memory; @@ -13,13 +14,15 @@ public sealed class Striker : IStriker private readonly ILogger _logger; private readonly IMemoryCache _cache; private readonly MemoryCacheEntryOptions _cacheOptions; - private readonly NotificationPublisher _notifier; + private readonly INotificationPublisher _notifier; + private readonly IDryRunInterceptor _dryRunInterceptor; - public Striker(ILogger logger, IMemoryCache cache, NotificationPublisher notifier) + public Striker(ILogger logger, IMemoryCache cache, INotificationPublisher notifier, IDryRunInterceptor dryRunInterceptor) { _logger = logger; _cache = cache; _notifier = notifier; + _dryRunInterceptor = dryRunInterceptor; _cacheOptions = new MemoryCacheEntryOptions() .SetSlidingExpiration(StaticConfiguration.TriggerValue + Constants.CacheLimitBuffer); } diff --git a/code/Infrastructure/Verticals/Jobs/GenericHandler.cs b/code/Infrastructure/Verticals/Jobs/GenericHandler.cs index 5a69cb0b..5e7adcd8 100644 --- a/code/Infrastructure/Verticals/Jobs/GenericHandler.cs +++ b/code/Infrastructure/Verticals/Jobs/GenericHandler.cs @@ -24,7 +24,7 @@ public abstract class GenericHandler : IHandler, IDisposable protected readonly ILidarrClient _lidarrClient; protected readonly ArrQueueIterator _arrArrQueueIterator; protected readonly IDownloadService _downloadService; - protected readonly NotificationPublisher _notifier; + protected readonly INotificationPublisher _notifier; protected GenericHandler( ILogger logger, @@ -37,7 +37,7 @@ public abstract class GenericHandler : IHandler, IDisposable ILidarrClient lidarrClient, ArrQueueIterator arrArrQueueIterator, DownloadServiceFactory downloadServiceFactory, - NotificationPublisher notifier + INotificationPublisher notifier ) { _logger = logger; diff --git a/code/Infrastructure/Verticals/Notifications/INotificationPublisher.cs b/code/Infrastructure/Verticals/Notifications/INotificationPublisher.cs new file mode 100644 index 00000000..5720a339 --- /dev/null +++ b/code/Infrastructure/Verticals/Notifications/INotificationPublisher.cs @@ -0,0 +1,12 @@ +using Domain.Enums; + +namespace Infrastructure.Verticals.Notifications; + +public interface INotificationPublisher +{ + Task NotifyStrike(StrikeType strikeType, int strikeCount); + + Task NotifyQueueItemDeleted(bool removeFromClient, DeleteReason reason); + + Task NotifyDownloadCleaned(double ratio, TimeSpan seedingTime, string categoryName, CleanReason reason); +} \ No newline at end of file diff --git a/code/Infrastructure/Verticals/Notifications/NotificationPublisher.cs b/code/Infrastructure/Verticals/Notifications/NotificationPublisher.cs index 7bbe2d68..28b30114 100644 --- a/code/Infrastructure/Verticals/Notifications/NotificationPublisher.cs +++ b/code/Infrastructure/Verticals/Notifications/NotificationPublisher.cs @@ -12,25 +12,19 @@ using Microsoft.Extensions.Logging; namespace Infrastructure.Verticals.Notifications; -public class NotificationPublisher : InterceptedService, IDryRunService +public class NotificationPublisher : INotificationPublisher { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IBus _messageBus; - - /// - /// Constructor to be used by interceptors. - /// - public NotificationPublisher() - { - } - - public NotificationPublisher(ILogger logger, IBus messageBus) + private readonly IDryRunInterceptor _dryRunInterceptor; + + public NotificationPublisher(ILogger logger, IBus messageBus, IDryRunInterceptor dryRunInterceptor) { _logger = logger; _messageBus = messageBus; + _dryRunInterceptor = dryRunInterceptor; } - [DryRunSafeguard] public virtual async Task NotifyStrike(StrikeType strikeType, int strikeCount) { try @@ -54,10 +48,10 @@ public class NotificationPublisher : InterceptedService, IDryRunService switch (strikeType) { case StrikeType.Stalled: - await _messageBus.Publish(notification.Adapt()); + await _dryRunInterceptor.InterceptAsync(Notify, notification.Adapt()); break; case StrikeType.ImportFailed: - await _messageBus.Publish(notification.Adapt()); + await _dryRunInterceptor.InterceptAsync(Notify, notification.Adapt()); break; } } @@ -67,7 +61,6 @@ public class NotificationPublisher : InterceptedService, IDryRunService } } - [DryRunSafeguard] public virtual async Task NotifyQueueItemDeleted(bool removeFromClient, DeleteReason reason) { QueueRecord record = ContextProvider.Get(nameof(QueueRecord)); @@ -86,10 +79,9 @@ public class NotificationPublisher : InterceptedService, IDryRunService Fields = [new() { Title = "Removed from download client?", Text = removeFromClient ? "Yes" : "No" }] }; - await _messageBus.Publish(notification); + await _dryRunInterceptor.InterceptAsync(Notify, notification); } - [DryRunSafeguard] public virtual async Task NotifyDownloadCleaned(double ratio, TimeSpan seedingTime, string categoryName, CleanReason reason) { DownloadCleanedNotification notification = new() @@ -106,7 +98,13 @@ public class NotificationPublisher : InterceptedService, IDryRunService Level = NotificationLevel.Important }; - await _messageBus.Publish(notification); + await _dryRunInterceptor.InterceptAsync(Notify, notification); + } + + [DryRunSafeguard] + private Task Notify(T message) where T: notnull + { + return _messageBus.Publish(message); } private static Uri GetImageFromContext(QueueRecord record, InstanceType instanceType) => diff --git a/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs b/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs index cdd49ad7..0bba5d1b 100644 --- a/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs +++ b/code/Infrastructure/Verticals/QueueCleaner/QueueCleaner.cs @@ -32,7 +32,7 @@ public sealed class QueueCleaner : GenericHandler LidarrClient lidarrClient, ArrQueueIterator arrArrQueueIterator, DownloadServiceFactory downloadServiceFactory, - NotificationPublisher notifier + INotificationPublisher notifier ) : base( logger, downloadClientConfig, sonarrConfig, radarrConfig, lidarrConfig,