From 7a56f7f586eb4b3adce77d3b21ed43d1b89d849f Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 20 Dec 2021 23:04:53 +0000 Subject: [PATCH] UserEventFirer, web hook tests --- Selector.CLI/DbWatcherService.cs | 10 +- Selector.CLI/Program.cs | 4 +- Selector.Event/CacheMappings/LastfmMapping.cs | 111 ++++++++-------- .../CacheMappings/NowPlayingMapping.cs | 88 +++++++++---- .../CacheMappings/SpotifyMapping.cs | 119 +++++++++--------- Selector.Event/Consumers/UserEventFirer.cs | 83 ++++++++++++ .../Consumers/UserEventFirerFactory.cs | 35 ++++++ .../Extensions/ServiceExtensions.cs | 3 + Selector.Event/UserEventBus.cs | 7 +- Selector.Tests/Consumer/WebHook.cs | 106 ++++++++++++++++ .../Pages/Account/Manage/Lastfm.cshtml | 2 +- .../Pages/Account/Manage/Spotify.cshtml | 2 +- Selector.Web/Startup.cs | 6 +- Selector/Consumers/WebHook.cs | 39 +++--- 14 files changed, 454 insertions(+), 161 deletions(-) create mode 100644 Selector.Event/Consumers/UserEventFirer.cs create mode 100644 Selector.Event/Consumers/UserEventFirerFactory.cs create mode 100644 Selector.Tests/Consumer/WebHook.cs diff --git a/Selector.CLI/DbWatcherService.cs b/Selector.CLI/DbWatcherService.cs index 50e2aec..19c3476 100644 --- a/Selector.CLI/DbWatcherService.cs +++ b/Selector.CLI/DbWatcherService.cs @@ -30,6 +30,8 @@ namespace Selector.CLI private readonly IAudioFeatureInjectorFactory AudioFeatureInjectorFactory; private readonly IPlayCounterFactory PlayCounterFactory; + private readonly IUserEventFirerFactory UserEventFirerFactory; + private readonly IPublisherFactory PublisherFactory; private readonly ICacheWriterFactory CacheWriterFactory; private ConcurrentDictionary Watchers { get; set; } = new(); @@ -48,7 +50,9 @@ namespace Selector.CLI IServiceProvider serviceProvider, IPublisherFactory publisherFactory = null, - ICacheWriterFactory cacheWriterFactory = null + ICacheWriterFactory cacheWriterFactory = null, + + IUserEventFirerFactory userEventFirerFactory = null ) { Logger = logger; @@ -62,6 +66,8 @@ namespace Selector.CLI AudioFeatureInjectorFactory = audioFeatureInjectorFactory; PlayCounterFactory = playCounterFactory; + UserEventFirerFactory = userEventFirerFactory; + PublisherFactory = publisherFactory; CacheWriterFactory = cacheWriterFactory; } @@ -123,6 +129,8 @@ namespace Selector.CLI if (CacheWriterFactory is not null) consumers.Add(await CacheWriterFactory.Get()); if (PublisherFactory is not null) consumers.Add(await PublisherFactory.Get()); + if (UserEventFirerFactory is not null) consumers.Add(await UserEventFirerFactory.Get()); + if (!string.IsNullOrWhiteSpace(dbWatcher.User.LastFmUsername)) { consumers.Add(await PlayCounterFactory.Get(creds: new() { Username = dbWatcher.User.LastFmUsername })); diff --git a/Selector.CLI/Program.cs b/Selector.CLI/Program.cs index f4d4324..1d9dfe3 100644 --- a/Selector.CLI/Program.cs +++ b/Selector.CLI/Program.cs @@ -125,8 +125,8 @@ namespace Selector.CLI services.AddRedisServices(config.RedisOptions.ConnectionString); Console.WriteLine("> Adding cache event maps..."); - services.AddTransient(); - services.AddTransient(); + services.AddTransient(); + services.AddTransient(); Console.WriteLine("> Adding caching Spotify consumers..."); services.AddCachingSpotify(); diff --git a/Selector.Event/CacheMappings/LastfmMapping.cs b/Selector.Event/CacheMappings/LastfmMapping.cs index a11fe73..9aeec28 100644 --- a/Selector.Event/CacheMappings/LastfmMapping.cs +++ b/Selector.Event/CacheMappings/LastfmMapping.cs @@ -14,74 +14,81 @@ namespace Selector.Events public string NewUsername { get; set; } } - public class LastfmFromCacheMapping : IEventMapping + public partial class FromPubSub { - private readonly ILogger Logger; - private readonly ISubscriber Subscriber; - private readonly UserEventBus UserEvent; - - public LastfmFromCacheMapping(ILogger logger, - ISubscriber subscriber, - UserEventBus userEvent) + public class Lastfm : IEventMapping { - Logger = logger; - Subscriber = subscriber; - UserEvent = userEvent; - } + private readonly ILogger Logger; + private readonly ISubscriber Subscriber; + private readonly UserEventBus UserEvent; - public async Task ConstructMapping() - { - Logger.LogDebug("Forming Last.fm username event mapping FROM cache TO event bus"); + public Lastfm(ILogger logger, + ISubscriber subscriber, + UserEventBus userEvent) + { + Logger = logger; + Subscriber = subscriber; + UserEvent = userEvent; + } - (await Subscriber.SubscribeAsync(Key.AllUserLastfm)).OnMessage(message => { - - try{ - var userId = Key.Param(message.Channel); + public async Task ConstructMapping() + { + Logger.LogDebug("Forming Last.fm username event mapping FROM cache TO event bus"); - var deserialised = JsonSerializer.Deserialize(message.Message); - Logger.LogDebug("Received new Last.fm username event for [{userId}]", deserialised.UserId); + (await Subscriber.SubscribeAsync(Key.AllUserLastfm)).OnMessage(message => { - if (!userId.Equals(deserialised.UserId)) + try { - Logger.LogWarning("Serialised user ID [{}] does not match cache channel [{}]", userId, deserialised.UserId); - } + var userId = Key.Param(message.Channel); - UserEvent.OnLastfmCredChange(this, deserialised); - } - catch(Exception e) - { - Logger.LogError(e, "Error parsing Last.fm username event"); - } - }); + var deserialised = JsonSerializer.Deserialize(message.Message); + Logger.LogDebug("Received new Last.fm username event for [{userId}]", deserialised.UserId); + + if (!userId.Equals(deserialised.UserId)) + { + Logger.LogWarning("Serialised user ID [{}] does not match cache channel [{}]", userId, deserialised.UserId); + } + + UserEvent.OnLastfmCredChange(this, deserialised); + } + catch (Exception e) + { + Logger.LogError(e, "Error parsing Last.fm username event"); + } + }); + } } } - public class LastfmToCacheMapping : IEventMapping + public partial class ToPubSub { - private readonly ILogger Logger; - private readonly ISubscriber Subscriber; - private readonly UserEventBus UserEvent; - - public LastfmToCacheMapping(ILogger logger, - ISubscriber subscriber, - UserEventBus userEvent) + public class Lastfm : IEventMapping { - Logger = logger; - Subscriber = subscriber; - UserEvent = userEvent; - } + private readonly ILogger Logger; + private readonly ISubscriber Subscriber; + private readonly UserEventBus UserEvent; - public Task ConstructMapping() - { - Logger.LogDebug("Forming Last.fm username event mapping TO cache FROM event bus"); - - UserEvent.LastfmCredChange += async (o, e) => + public Lastfm(ILogger logger, + ISubscriber subscriber, + UserEventBus userEvent) { - var payload = JsonSerializer.Serialize(e); - await Subscriber.PublishAsync(Key.UserLastfm(e.UserId), payload); - }; + Logger = logger; + Subscriber = subscriber; + UserEvent = userEvent; + } - return Task.CompletedTask; + public Task ConstructMapping() + { + Logger.LogDebug("Forming Last.fm username event mapping TO cache FROM event bus"); + + UserEvent.LastfmCredChange += async (o, e) => + { + var payload = JsonSerializer.Serialize(e); + await Subscriber.PublishAsync(Key.UserLastfm(e.UserId), payload); + }; + + return Task.CompletedTask; + } } } } \ No newline at end of file diff --git a/Selector.Event/CacheMappings/NowPlayingMapping.cs b/Selector.Event/CacheMappings/NowPlayingMapping.cs index ed8fdc0..d7970b2 100644 --- a/Selector.Event/CacheMappings/NowPlayingMapping.cs +++ b/Selector.Event/CacheMappings/NowPlayingMapping.cs @@ -7,40 +7,78 @@ using Selector.Cache; namespace Selector.Events { - public class NowPlayingFromCacheMapping : IEventMapping + public partial class FromPubSub { - private readonly ILogger Logger; - private readonly ISubscriber Subscriber; - private readonly UserEventBus UserEvent; - - public NowPlayingFromCacheMapping(ILogger logger, - ISubscriber subscriber, - UserEventBus userEvent) + public class NowPlaying : IEventMapping { - Logger = logger; - Subscriber = subscriber; - UserEvent = userEvent; + private readonly ILogger Logger; + private readonly ISubscriber Subscriber; + private readonly UserEventBus UserEvent; + + public NowPlaying(ILogger logger, + ISubscriber subscriber, + UserEventBus userEvent) + { + Logger = logger; + Subscriber = subscriber; + UserEvent = userEvent; + } + + public async Task ConstructMapping() + { + Logger.LogDebug("Forming now playing event mapping between cache and event bus"); + + (await Subscriber.SubscribeAsync(Key.AllCurrentlyPlaying)).OnMessage(message => { + + try + { + var userId = Key.Param(message.Channel); + + var deserialised = JsonSerializer.Deserialize(message.Message); + Logger.LogDebug("Received new currently playing [{username}]", deserialised.Username); + + UserEvent.OnCurrentlyPlayingChange(this, userId, deserialised); + } + catch (Exception e) + { + Logger.LogError(e, $"Error parsing new currently playing [{message}]"); + } + }); + } } + } - public async Task ConstructMapping() + public partial class ToPubSub + { + public class NowPlaying : IEventMapping { - Logger.LogDebug("Forming now playing event mapping between cache and event bus"); + private readonly ILogger Logger; + private readonly ISubscriber Subscriber; + private readonly UserEventBus UserEvent; - (await Subscriber.SubscribeAsync(Key.AllCurrentlyPlaying)).OnMessage(message => { - - try{ - var userId = Key.Param(message.Channel); + public NowPlaying(ILogger logger, + ISubscriber subscriber, + UserEventBus userEvent) + { + Logger = logger; + Subscriber = subscriber; + UserEvent = userEvent; + } - var deserialised = JsonSerializer.Deserialize(message.Message); - Logger.LogDebug("Received new currently playing [{username}]", deserialised.Username); + public Task ConstructMapping() + { + Logger.LogDebug("Forming now playing event mapping TO cache FROM event bus"); - UserEvent.OnCurrentlyPlayingChange(this, userId, deserialised); - } - catch(Exception e) + UserEvent.CurrentlyPlaying += async (o, e) => { - Logger.LogError(e, $"Error parsing new currently playing [{message}]"); - } - }); + (string id, CurrentlyPlayingDTO args) = e; + + var payload = JsonSerializer.Serialize(e); + await Subscriber.PublishAsync(Key.CurrentlyPlaying(id), payload); + }; + + return Task.CompletedTask; + } } } } \ No newline at end of file diff --git a/Selector.Event/CacheMappings/SpotifyMapping.cs b/Selector.Event/CacheMappings/SpotifyMapping.cs index f3f0cb0..d91ad75 100644 --- a/Selector.Event/CacheMappings/SpotifyMapping.cs +++ b/Selector.Event/CacheMappings/SpotifyMapping.cs @@ -14,78 +14,85 @@ namespace Selector.Events public bool NewLinkState { get; set; } } - public class SpotifyLinkFromCacheMapping : IEventMapping + public partial class FromPubSub { - private readonly ILogger Logger; - private readonly ISubscriber Subscriber; - private readonly UserEventBus UserEvent; - - public SpotifyLinkFromCacheMapping(ILogger logger, - ISubscriber subscriber, - UserEventBus userEvent) + public class SpotifyLink : IEventMapping { - Logger = logger; - Subscriber = subscriber; - UserEvent = userEvent; - } + private readonly ILogger Logger; + private readonly ISubscriber Subscriber; + private readonly UserEventBus UserEvent; - public async Task ConstructMapping() - { - Logger.LogDebug("Forming Spotify link event mapping FROM cache TO event bus"); + public SpotifyLink(ILogger logger, + ISubscriber subscriber, + UserEventBus userEvent) + { + Logger = logger; + Subscriber = subscriber; + UserEvent = userEvent; + } - (await Subscriber.SubscribeAsync(Key.AllUserSpotify)).OnMessage(message => { - - try{ - var userId = Key.Param(message.Channel); + public async Task ConstructMapping() + { + Logger.LogDebug("Forming Spotify link event mapping FROM cache TO event bus"); - var deserialised = JsonSerializer.Deserialize(message.Message); - Logger.LogDebug("Received new Spotify link event for [{userId}]", deserialised.UserId); + (await Subscriber.SubscribeAsync(Key.AllUserSpotify)).OnMessage(message => { - if (!userId.Equals(deserialised.UserId)) + try { - Logger.LogWarning("Serialised user ID [{}] does not match cache channel [{}]", userId, deserialised.UserId); - } + var userId = Key.Param(message.Channel); - UserEvent.OnSpotifyLinkChange(this, deserialised); - } - catch(TaskCanceledException) - { - Logger.LogDebug("Task Cancelled"); - } - catch(Exception e) - { - Logger.LogError(e, "Error parsing new Spotify link event"); - } - }); + var deserialised = JsonSerializer.Deserialize(message.Message); + Logger.LogDebug("Received new Spotify link event for [{userId}]", deserialised.UserId); + + if (!userId.Equals(deserialised.UserId)) + { + Logger.LogWarning("Serialised user ID [{}] does not match cache channel [{}]", userId, deserialised.UserId); + } + + UserEvent.OnSpotifyLinkChange(this, deserialised); + } + catch (TaskCanceledException) + { + Logger.LogDebug("Task Cancelled"); + } + catch (Exception e) + { + Logger.LogError(e, "Error parsing new Spotify link event"); + } + }); + } } } - public class SpotifyLinkToCacheMapping : IEventMapping + public partial class ToPubSub { - private readonly ILogger Logger; - private readonly ISubscriber Subscriber; - private readonly UserEventBus UserEvent; - - public SpotifyLinkToCacheMapping(ILogger logger, - ISubscriber subscriber, - UserEventBus userEvent) + public class SpotifyLink : IEventMapping { - Logger = logger; - Subscriber = subscriber; - UserEvent = userEvent; - } + private readonly ILogger Logger; + private readonly ISubscriber Subscriber; + private readonly UserEventBus UserEvent; - public Task ConstructMapping() - { - Logger.LogDebug("Forming Spotify link event mapping TO cache FROM event bus"); - - UserEvent.SpotifyLinkChange += async (o, e) => + public SpotifyLink(ILogger logger, + ISubscriber subscriber, + UserEventBus userEvent) { - var payload = JsonSerializer.Serialize(e); - await Subscriber.PublishAsync(Key.UserSpotify(e.UserId), payload); - }; + Logger = logger; + Subscriber = subscriber; + UserEvent = userEvent; + } - return Task.CompletedTask; + public Task ConstructMapping() + { + Logger.LogDebug("Forming Spotify link event mapping TO cache FROM event bus"); + + UserEvent.SpotifyLinkChange += async (o, e) => + { + var payload = JsonSerializer.Serialize(e); + await Subscriber.PublishAsync(Key.UserSpotify(e.UserId), payload); + }; + + return Task.CompletedTask; + } } } } \ No newline at end of file diff --git a/Selector.Event/Consumers/UserEventFirer.cs b/Selector.Event/Consumers/UserEventFirer.cs new file mode 100644 index 0000000..0278ba6 --- /dev/null +++ b/Selector.Event/Consumers/UserEventFirer.cs @@ -0,0 +1,83 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +using Selector.Events; + +namespace Selector +{ + public class UserEventFirer : IConsumer + { + protected readonly IPlayerWatcher Watcher; + protected readonly ILogger Logger; + + protected readonly UserEventBus UserEvent; + + public CancellationToken CancelToken { get; set; } + + public UserEventFirer( + IPlayerWatcher watcher, + UserEventBus userEvent, + ILogger logger = null, + CancellationToken token = default + ) + { + Watcher = watcher; + UserEvent = userEvent; + Logger = logger ?? NullLogger.Instance; + CancelToken = token; + } + + public void Callback(object sender, ListeningChangeEventArgs e) + { + if (e.Current is null) return; + + Task.Run(async () => { + try + { + await AsyncCallback(e); + } + catch (Exception e) + { + Logger.LogError(e, "Error occured during callback"); + } + }, CancelToken); + } + + public Task AsyncCallback(ListeningChangeEventArgs e) + { + Logger.LogDebug("Firing now playing event on user bus [{username}/{userId}]", e.SpotifyUsername, e.Id); + + UserEvent.OnCurrentlyPlayingChange(this, e.Id, (CurrentlyPlayingDTO) e); + + return Task.CompletedTask; + } + + public void Subscribe(IWatcher watch = null) + { + var watcher = watch ?? Watcher ?? throw new ArgumentNullException("No watcher provided"); + + if (watcher is IPlayerWatcher watcherCast) + { + watcherCast.ItemChange += Callback; + } + else + { + throw new ArgumentException("Provided watcher is not a PlayerWatcher"); + } + } + + public void Unsubscribe(IWatcher watch = null) + { + var watcher = watch ?? Watcher ?? throw new ArgumentNullException("No watcher provided"); + + if (watcher is IPlayerWatcher watcherCast) + { + watcherCast.ItemChange -= Callback; + } + else + { + throw new ArgumentException("Provided watcher is not a PlayerWatcher"); + } + } + } +} diff --git a/Selector.Event/Consumers/UserEventFirerFactory.cs b/Selector.Event/Consumers/UserEventFirerFactory.cs new file mode 100644 index 0000000..3746f17 --- /dev/null +++ b/Selector.Event/Consumers/UserEventFirerFactory.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Selector.Events; + +namespace Selector +{ + public interface IUserEventFirerFactory + { + public Task Get(IPlayerWatcher watcher = null); + } + + public class UserEventFirerFactory: IUserEventFirerFactory + { + private readonly ILoggerFactory LoggerFactory; + private readonly UserEventBus UserEvent; + + public UserEventFirerFactory(ILoggerFactory loggerFactory, UserEventBus userEvent) + { + LoggerFactory = loggerFactory; + UserEvent = userEvent; + } + + public Task Get(IPlayerWatcher watcher = null) + { + return Task.FromResult(new UserEventFirer( + watcher, + UserEvent, + LoggerFactory.CreateLogger() + )); + } + } +} diff --git a/Selector.Event/Extensions/ServiceExtensions.cs b/Selector.Event/Extensions/ServiceExtensions.cs index 9700ed0..d23b2f2 100644 --- a/Selector.Event/Extensions/ServiceExtensions.cs +++ b/Selector.Event/Extensions/ServiceExtensions.cs @@ -8,6 +8,9 @@ namespace Selector.Events { services.AddEventBus(); services.AddEventMappingAgent(); + + services.AddTransient(); + services.AddTransient(); } public static void AddEventBus(this IServiceCollection services) diff --git a/Selector.Event/UserEventBus.cs b/Selector.Event/UserEventBus.cs index db710df..c4e394c 100644 --- a/Selector.Event/UserEventBus.cs +++ b/Selector.Event/UserEventBus.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Selector.Model; diff --git a/Selector.Tests/Consumer/WebHook.cs b/Selector.Tests/Consumer/WebHook.cs new file mode 100644 index 0000000..e699afd --- /dev/null +++ b/Selector.Tests/Consumer/WebHook.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Net.Http; + +using Xunit; +using Moq; +using Moq.Protected; +using FluentAssertions; +using System.Net; + +using SpotifyAPI.Web; + +namespace Selector.Tests +{ + public class WebHookTest + { + [Fact(Skip = "Not working atm")] + public async Task TestHttpClientUsed() + { + var msg = new HttpResponseMessage(HttpStatusCode.OK); + + var httpHandlerMock = new Mock(); + httpHandlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(msg); + + var watcherMock = new Mock(); + watcherMock.SetupAdd(w => w.ItemChange += It.IsAny>()); + watcherMock.SetupRemove(w => w.ItemChange -= It.IsAny>()); + + var link = "https://link"; + var content = new StringContent(""); + var config = new WebHookConfig() + { + Url = link, + Content = content, + }; + + var http = new HttpClient(httpHandlerMock.Object); + + var webHook = new WebHook(watcherMock.Object, http, config); + + webHook.Subscribe(); + watcherMock.Raise(w => w.ItemChange += null, this, new ListeningChangeEventArgs()); + + await Task.Delay(100); + + httpHandlerMock.Protected().Verify>("SendAsync", Times.Once(), ItExpr.IsAny(), ItExpr.IsAny()); + } + + [Theory] + [InlineData(200, true, true)] + [InlineData(404, true, false)] + [InlineData(500, true, false)] + public async Task TestEventFiring(int code, bool predicate, bool successful) + { + var msg = new HttpResponseMessage(Enum.Parse(code.ToString())); + + var httpHandlerMock = new Mock(); + httpHandlerMock.Protected() + .Setup>("SendAsync", ItExpr.IsAny(), ItExpr.IsAny()) + .ReturnsAsync(msg); + + var watcherMock = new Mock(); + + var link = "https://link"; + var content = new StringContent(""); + var config = new WebHookConfig() + { + Url = link, + Content = content, + }; + + var http = new HttpClient(httpHandlerMock.Object); + + bool predicateEvent = false, successfulEvent = false, failedEvent = false; + + var webHook = new WebHook(watcherMock.Object, http, config); + + webHook.PredicatePass += (o, e) => + { + predicateEvent = predicate; + }; + + webHook.SuccessfulRequest += (o, e) => + { + successfulEvent = successful; + }; + + webHook.FailedRequest += (o, e) => + { + failedEvent = !successful; + }; + + await webHook.AsyncCallback(ListeningChangeEventArgs.From(new (), new (), new())); + + predicateEvent.Should().Be(predicate); + successfulEvent.Should().Be(successful); + failedEvent.Should().Be(!successful); + } + } +} diff --git a/Selector.Web/Areas/Identity/Pages/Account/Manage/Lastfm.cshtml b/Selector.Web/Areas/Identity/Pages/Account/Manage/Lastfm.cshtml index e81e942..97b373d 100644 --- a/Selector.Web/Areas/Identity/Pages/Account/Manage/Lastfm.cshtml +++ b/Selector.Web/Areas/Identity/Pages/Account/Manage/Lastfm.cshtml @@ -5,7 +5,7 @@ ViewData["ActivePage"] = ManageNavPages.LastFm; } -

@ViewData["Title"]

+

@ViewData["Title"]

diff --git a/Selector.Web/Areas/Identity/Pages/Account/Manage/Spotify.cshtml b/Selector.Web/Areas/Identity/Pages/Account/Manage/Spotify.cshtml index 4d0904d..b7dd5ff 100644 --- a/Selector.Web/Areas/Identity/Pages/Account/Manage/Spotify.cshtml +++ b/Selector.Web/Areas/Identity/Pages/Account/Manage/Spotify.cshtml @@ -5,7 +5,7 @@ ViewData["ActivePage"] = ManageNavPages.Spotify; } -

@ViewData["Title"]

+

@ViewData["Title"]

diff --git a/Selector.Web/Startup.cs b/Selector.Web/Startup.cs index 1f5f417..2e900d2 100644 --- a/Selector.Web/Startup.cs +++ b/Selector.Web/Startup.cs @@ -107,9 +107,9 @@ namespace Selector.Web Console.WriteLine("> Adding cache event maps..."); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddCacheHubProxy(); diff --git a/Selector/Consumers/WebHook.cs b/Selector/Consumers/WebHook.cs index 01d2de0..2cd5c5e 100644 --- a/Selector/Consumers/WebHook.cs +++ b/Selector/Consumers/WebHook.cs @@ -38,9 +38,9 @@ namespace Selector protected readonly WebHookConfig Config; - protected event EventHandler PredicatePass; - protected event EventHandler SuccessfulRequest; - protected event EventHandler FailedRequest; + public event EventHandler PredicatePass; + public event EventHandler SuccessfulRequest; + public event EventHandler FailedRequest; public CancellationToken CancelToken { get; set; } @@ -81,20 +81,31 @@ namespace Selector { if(Config.ShouldRequest(e)) { - Logger.LogDebug("[{name}] predicate passed, making request to [{url}]", Config.Name, Config.Url); - var response = await HttpClient.PostAsync(Config.Url, Config.Content, CancelToken); - - OnPredicatePass(new EventArgs()); - - if (response.IsSuccessStatusCode) + try { - Logger.LogDebug("[{name}] request success", Config.Name); - OnSuccessfulRequest(new EventArgs()); + Logger.LogDebug("[{name}] predicate passed, making request to [{url}]", Config.Name, Config.Url); + OnPredicatePass(new EventArgs()); + + var response = await HttpClient.PostAsync(Config.Url, Config.Content, CancelToken); + + if (response.IsSuccessStatusCode) + { + Logger.LogDebug("[{name}] request success", Config.Name); + OnSuccessfulRequest(new EventArgs()); + } + else + { + Logger.LogDebug("[{name}] request failed [{error}] [{content}]", Config.Name, response.StatusCode, response.Content); + OnFailedRequest(new EventArgs()); + } } - else + catch(HttpRequestException ex) { - Logger.LogDebug("[{name}] request failed [{error}] [{content}]", Config.Name, response.StatusCode, response.Content); - OnFailedRequest(new EventArgs()); + Logger.LogError(ex, "Exception occured during request"); + } + catch (TaskCanceledException) + { + Logger.LogDebug("Task cancelled"); } } else