public void WhenSearch_ThenReturnsActiveSubscriptions() { var config = new SubscriptionRelayConfig { Config = new SubscriptionConfig { Url = "aurl" } }; store.Setup(s => s.Search("aneventname", true)) .Returns(new List <SubscriptionRelayConfig> { config }); var result = service.Get(new SearchSubscriptions { EventName = "aneventname" }); Assert.That(result.Subscribers.Count, Is.EqualTo(1)); Assert.That(result.Subscribers[0], Is.EqualTo(config)); store.Verify(s => s.Search("aneventname", true)); }
public void WhenWrite_ThenPostsEventToSubscribers() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); var result = processor.ProcessMessage(new WebhookEvent { EventName = "aneventname", Data = "adata" }); Assert.That(result, Is.True); subscriptionCache.Verify(sc => sc.GetAll("aneventname")); serviceClient.VerifySet(sc => sc.Retries = EventRelayQueueProcessor.DefaultServiceClientRetries); serviceClient.VerifySet(sc => sc.Timeout = TimeSpan.FromSeconds(EventRelayQueueProcessor.DefaultServiceClientTimeoutSeconds)); serviceClient.Verify(sc => sc.Relay(config, It.Is <WebhookEvent>(whe => whe.Data.ToString() == "adata" && whe.EventName == "aneventname" ))); }
public void WhenWrite_ThenPostsEventToSubscribersAndUpdatesResults() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); var result = new SubscriptionDeliveryResult(); serviceClient.Setup(sc => sc.Relay(config, It.IsAny <WebhookEvent>())) .Returns(result); processor.ProcessMessage(new WebhookEvent { EventName = "aneventname", Data = new Dictionary <string, string> { { "akey", "avalue" } } }); subscriptionService.Verify(ss => ss.UpdateResults(It.Is <List <SubscriptionDeliveryResult> >(results => results.Count == 1 && results[0] == result))); }
/// <summary> /// Creates an instance of a serviceclient and configures it to send an event notification. /// See: https://developer.github.com/webhooks/#payloads for specification /// </summary> private IServiceClient CreateServiceClient(SubscriptionRelayConfig relayConfig, string eventName, TimeSpan?timeout) { try { var client = ServiceClientFactory.Create(relayConfig.Config.Url); client.Timeout = timeout; client.RequestFilter = request => { request.ContentType = MimeTypes.Json; request.Headers.Remove(WebhookEventConstants.SecretSignatureHeaderName); request.Headers.Remove(WebhookEventConstants.RequestIdHeaderName); request.Headers.Remove(WebhookEventConstants.EventNameHeaderName); if (relayConfig.Config.ContentType.HasValue()) { request.ContentType = relayConfig.Config.ContentType; } if (relayConfig.Config.Secret.HasValue()) { request.Headers.Add(WebhookEventConstants.SecretSignatureHeaderName, CreateContentHmacSignature(request, relayConfig.Config.Secret)); } request.Headers.Add(WebhookEventConstants.RequestIdHeaderName, CreateRequestIdentifier()); request.Headers.Add(WebhookEventConstants.EventNameHeaderName, eventName); }; return(client); } catch (Exception ex) { logger.Error(@"Failed to connect to subscriber: {0}, this URL is not valid".Fmt(relayConfig.Config.Url), ex); return(null); } }
public SubscriptionDeliveryResult Relay(SubscriptionRelayConfig subscription, WebhookEvent webhookEvent) { Guard.AgainstNull(() => subscription, subscription); Guard.AgainstNull(() => webhookEvent, webhookEvent); var serviceClient = CreateServiceClient(subscription, webhookEvent.EventName, Timeout); var attempts = 0; while (attempts <= Retries) { attempts++; try { var url = subscription.Config.Url; logger.InfoFormat("[ServiceStack.Webhooks.Relays.Clients.EventServiceClient] Notifying {0} of webhook event {1}", url, webhookEvent.ToJson()); using (var response = serviceClient.Post(url, webhookEvent.Data)) { return(CreateDeliveryResult(subscription.SubscriptionId, webhookEvent.Id, response.StatusCode, response.StatusDescription)); } } catch (WebServiceException ex) { if (HasNoMoreRetries(attempts) || ex.IsAny400()) { logger.Warn("[ServiceStack.Webhooks.Relays.Clients.EventServiceClient] " + Resources.EventServiceClient_FailedDelivery.Fmt(subscription.Config.Url, attempts), ex); return(CreateDeliveryResult(subscription.SubscriptionId, webhookEvent.Id, (HttpStatusCode)ex.StatusCode, ex.StatusDescription)); } } catch (Exception ex) { // Timeout (WebException) or other Exception if (HasNoMoreRetries(attempts)) { var message = "[ServiceStack.Webhooks.Relays.Clients.EventServiceClient] " + Resources.EventServiceClient_FailedDelivery.Fmt(subscription.Config.Url, attempts); logger.Warn(message, ex); return(CreateDeliveryResult(subscription.SubscriptionId, webhookEvent.Id, HttpStatusCode.ServiceUnavailable, message)); } } } return(null); }
public void WhenWrite_ThenPostsEventToSubscribers() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); sink.Write("aneventname", new Dictionary <string, string> { { "akey", "avalue" } }); subscriptionCache.Verify(sc => sc.GetAll("aneventname")); serviceClient.VerifySet(sc => sc.Retries = AppHostEventSink.DefaultServiceClientRetries); serviceClient.VerifySet(sc => sc.Timeout = TimeSpan.FromSeconds(AppHostEventSink.DefaultServiceClientTimeoutSeconds)); serviceClient.Verify(sc => sc.Relay(config, "aneventname", It.Is <Dictionary <string, string> >(dic => dic["akey"] == "avalue"))); }
public SubscriptionDeliveryResult Relay(SubscriptionRelayConfig subscription, string eventName, object data) { Guard.AgainstNull(() => subscription, subscription); Guard.AgainstNullOrEmpty(() => eventName, eventName); var serviceClient = CreateServiceClient(subscription, eventName, Timeout); var attempts = 0; while (attempts <= Retries) { attempts++; try { using (var response = serviceClient.Post(subscription.Config.Url, data)) { return(CreateDeliveryResult(subscription.SubscriptionId, response.StatusCode, response.StatusDescription)); } } catch (WebServiceException ex) { if (HasNoMoreRetries(attempts) || ex.IsAny400()) { logger.Warn(Resources.EventServiceClient_FailedDelivery.Fmt(subscription.Config.Url, attempts), ex); return(CreateDeliveryResult(subscription.SubscriptionId, (HttpStatusCode)ex.StatusCode, ex.StatusDescription)); } } catch (Exception ex) { // Timeout (WebException) or other Exception if (HasNoMoreRetries(attempts)) { var message = Resources.EventServiceClient_FailedDelivery.Fmt(subscription.Config.Url, attempts); logger.Warn(message, ex); return(CreateDeliveryResult(subscription.SubscriptionId, HttpStatusCode.ServiceUnavailable, message)); } } } return(null); }
public void WhenWrite_ThenPostsEventToSubscribers() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); var whe = new WebhookEvent { EventName = "aneventname" }; sink.Write(whe); subscriptionCache.Verify(sc => sc.GetAll("aneventname")); serviceClient.VerifySet(sc => sc.Retries = AppHostEventSink.DefaultServiceClientRetries); serviceClient.VerifySet(sc => sc.Timeout = TimeSpan.FromSeconds(AppHostEventSink.DefaultServiceClientTimeoutSeconds)); serviceClient.Verify(sc => sc.Relay(config, whe)); }
public void WhenGetAllAndCached_ThenReturnsSubscriptions() { var config = new SubscriptionRelayConfig(); var subscribers = new List <SubscriptionRelayConfig> { config }; cacheClient.Setup(cc => cc.Get <CachedSubscription>(It.IsAny <string>())) .Returns(new CachedSubscription { Subscribers = subscribers }); var result = cache.GetAll("aneventname"); Assert.That(result.Count, Is.EqualTo(1)); Assert.That(result[0], Is.EqualTo(config)); cacheClient.Verify(cc => cc.Get <CachedSubscription>(CacheClientEventSubscriptionCache.FormatCacheKey("aneventname"))); subscriptionService.Verify(ss => ss.Search(It.IsAny <string>()), Times.Never); cacheClient.Verify(cc => cc.Set(It.IsAny <string>(), It.IsAny <CachedSubscription>()), Times.Never); }
public void WhenGetAllAndNothingInCache_ThenCachesSubscriptions() { var config = new SubscriptionRelayConfig(); var subscribers = new List <SubscriptionRelayConfig> { config }; cacheClient.Setup(cc => cc.Get <CachedSubscription>(It.IsAny <string>())) .Returns((CachedSubscription)null); subscriptionService.Setup(ss => ss.Search(It.IsAny <string>())) .Returns(subscribers); var result = cache.GetAll("aneventname"); Assert.That(result.Count, Is.EqualTo(1)); Assert.That(result[0], Is.EqualTo(config)); cacheClient.Verify(cc => cc.Get <CachedSubscription>(CacheClientEventSubscriptionCache.FormatCacheKey("aneventname"))); subscriptionService.Verify(ss => ss.Search("aneventname")); cacheClient.Verify(cc => cc.Set(CacheClientEventSubscriptionCache.FormatCacheKey("aneventname"), It.Is <CachedSubscription>(cs => cs.Subscribers == subscribers), TimeSpan.FromSeconds(cache.ExpiryTimeSeconds))); }
public void WhenWrite_ThenPostsEventToSubscribersAndUpdatesResults() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); var data = new Dictionary <string, string> { { "akey", "avalue" } }; var result = new SubscriptionDeliveryResult(); serviceClient.Setup(sc => sc.Relay(config, "aneventname", data)) .Returns(result); sink.Write("aneventname", data); subscriptionService.Verify(ss => ss.UpdateResults(It.Is <List <SubscriptionDeliveryResult> >(results => (results.Count == 1) && (results[0] == result)))); }
public void WhenWrite_ThenPostsEventToSubscribersAndUpdatesResults() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); var result = new SubscriptionDeliveryResult(); var whe = new WebhookEvent { EventName = "aneventname" }; serviceClient.Setup(sc => sc.Relay(config, whe)) .Returns(result); sink.Write(whe); subscriptionService.Verify(ss => ss.UpdateResults(It.Is <List <SubscriptionDeliveryResult> >(results => results.Count == 1 && results[0] == result))); }
private SubscriptionDeliveryResult NotifySubscription(SubscriptionRelayConfig subscription, string eventName, Dictionary <string, string> data) { ServiceClient.Retries = Retries; ServiceClient.Timeout = TimeSpan.FromSeconds(TimeoutSecs); return(ServiceClient.Relay(subscription, eventName, data)); }
private SubscriptionDeliveryResult NotifySubscription(SubscriptionRelayConfig subscription, WebhookEvent webhookEvent) { ServiceClient.Retries = Retries; ServiceClient.Timeout = TimeSpan.FromSeconds(TimeoutSecs); return(ServiceClient.Relay(subscription, webhookEvent)); }