Ejemplo n.º 1
0
        public override async Task <WebhookSendResponse> SendWebHookAsync(WebhookWorkItem webHookWorkItem)
        {
            // Retry in the following intervals (in minutes): 1, 2, 4, …, 2^(RetryCount-1)
            var policy = Policy.Handle <WebHookSendException>().WaitAndRetryAsync(RetryCount, retryAttempt => TimeSpan.FromMinutes(Math.Pow(2, retryAttempt - 1)));

            return(await policy.ExecuteAsync(() => PerformSend(webHookWorkItem)));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates an <see cref="HttpRequestMessage"/> containing the headers and body by given <paramref name="workItem"/>.
        /// </summary>
        /// <param name="workItem">A <see cref="WebhookWorkItem"/> representing the <see cref="Webhook"/> to be sent.</param>
        /// <returns>A filled in <see cref="HttpRequestMessage"/>.</returns>
        //[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Request is disposed by caller.")]
        protected virtual HttpRequestMessage CreateWebHookRequest(WebhookWorkItem workItem)
        {
            if (workItem == null)
            {
                throw new ArgumentNullException(nameof(workItem));
            }

            var webHook = workItem.WebHook;

            // Create WebHook request
            var request = new HttpRequestMessage(HttpMethod.Post, webHook.Url);

            // Fills in request body and headers

            CreateWebHookRequestBody(workItem, request);

            foreach (var kvp in webHook.RequestParams.Headers)
            {
                if (!request.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value) && !request.Content.Headers.TryAddWithoutValidation(kvp.Key, kvp.Value))
                {
                    var errorMessage = string.Format(CultureInfo.CurrentCulture, InvalidHeaderTemplate, kvp.Key, webHook.Id);

                    throw new WebHookSendException(errorMessage, webHook.Id, workItem.EventId);
                }
            }

            return(request);
        }
Ejemplo n.º 3
0
 protected virtual Task HandleResponseAsync(WebhookWorkItem webHookWorkItem, WebhookSendResponse webHookSendResponse)
 {
     if (webHookSendResponse.IsSuccessfull)
     {
         return(HandleSuccessAsync(webHookWorkItem, webHookSendResponse));
     }
     else
     {
         return(HandleErrorAsync(webHookWorkItem, webHookSendResponse));
     }
 }
Ejemplo n.º 4
0
        private static void CreateWebHookRequestBody(WebhookWorkItem workItem, HttpRequestMessage request)
        {
            var body = new Dictionary <string, object>
            {
                // Set properties from work item
                [EventIdKey]   = workItem.EventId,
                [AttemptKey]   = (workItem.FeedEntry?.AttemptCount ?? 0) + 1,
                [EventBodyKey] = workItem.WebHook.RequestParams.Body,
            };

            var bodyJObject = JObject.FromObject(body).ToString();

            request.Content = new StringContent(bodyJObject, Encoding.UTF8, "application/json");
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates <see cref="WebhookFeedEntry"/> from <see cref="webHookWorkItem"/>. If it already has <see cref="WebhookFeedEntry"/>, inreases AttemptCount.
        /// </summary>
        /// <param name="webHookWorkItem"></param>
        /// <param name="webHookSendResponse"></param>
        /// <returns></returns>
        protected virtual WebhookFeedEntry GetOrCreateFeedEntry(WebhookWorkItem webHookWorkItem, WebhookSendResponse webHookSendResponse)
        {
            var feedEntry = webHookWorkItem.FeedEntry;

            if (feedEntry == null)
            {
                feedEntry = WebHookFeedUtils.CreateErrorEntry(webHookWorkItem, webHookSendResponse);
            }
            else
            {
                feedEntry.AttemptCount++;
            }

            return(feedEntry);
        }
Ejemplo n.º 6
0
        protected virtual async Task HandleSuccessAsync(WebhookWorkItem webHookWorkItem, WebhookSendResponse webHookSendResponse)
        {
            // Clear error records on this sending after success
            if (webHookWorkItem.FeedEntry?.RecordType == (int)WebhookFeedEntryType.Error && !webHookWorkItem.FeedEntry.IsTransient())
            {
                await _webHookFeedService.DeleteByIdsAsync(new[] { webHookWorkItem.FeedEntry.Id });
            }

            // Create new record (not using and updating existing one!) for proper logging, as all Success entries are accumulated in one record in our current logging policy.
            var feedEntry = WebHookFeedUtils.CreateSuccessEntry(webHookWorkItem, webHookSendResponse);

            await _logger.LogAsync(feedEntry);

            webHookWorkItem.FeedEntry = feedEntry;
        }
Ejemplo n.º 7
0
        protected virtual async Task HandleErrorAsync(WebhookWorkItem webHookWorkItem, WebhookSendResponse webHookSendResponse)
        {
            var feedEntry = GetOrCreateFeedEntry(webHookWorkItem, webHookSendResponse);

            feedEntry.RecordType = (int)WebhookFeedEntryType.Error;
            feedEntry.Status     = webHookSendResponse?.StatusCode ?? webHookWorkItem.FeedEntry.Status;

            await _logger.LogAsync(feedEntry);

            webHookWorkItem.FeedEntry = feedEntry;

            //delete old FeedEntries except latest by 'LatestErrorCount'
            var errorFeedEntryIds = await _webHookFeedService.GetAllErrorEntriesExceptLatestAsync(new[] { webHookWorkItem.WebHook.Id }, LatestErrorCount);

            await _webHookFeedService.DeleteByIdsAsync(errorFeedEntryIds);
        }
        protected virtual async Task <WebhookSendResponse> NotifyWebHook(string eventId, string eventObject, Webhook webHook, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            WebhookSendResponse response = null;

            var webHookWorkItem = new WebhookWorkItem()
            {
                EventId = eventId,
                WebHook = webHook,
            };

            webHook.RequestParams = new WebhookHttpParams()
            {
                Body = eventObject,
            };

            response = await _webHookSender.SendWebHookAsync(webHookWorkItem);

            return(response);
        }
Ejemplo n.º 9
0
        private async Task <WebhookSendResponse> PerformSend(WebhookWorkItem webHookWorkItem)
        {
            var result = new WebhookSendResponse();

            try
            {
                var request    = CreateWebHookRequest(webHookWorkItem);
                var httpClient = _httpClientFactory.CreateClient("webhooks");

                var response = await httpClient.SendAsync(request);

                var responseContent = await response.Content.ReadAsStringAsync();

                result = CreateSendResponse(response, responseContent);

                if (!response.IsSuccessStatusCode)
                {
                    throw new WebHookSendException(responseContent, webHookWorkItem.WebHook.Id, webHookWorkItem.EventId);
                }

                return(result);
            }
            catch (WebHookSendException ex)
            {
                result.Error = GetErrorText(webHookWorkItem.FeedEntry?.AttemptCount + 1 ?? 0, ex.Message);
                throw;
            }
            catch (Exception ex)
            {
                result.Error = ex.Message;
                return(result);
            }
            finally
            {
                await HandleResponseAsync(webHookWorkItem, result);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Gets the current <see cref="ILogger"/> instance.
        /// </summary>

        /// <inheritdoc />
        public abstract Task <WebhookSendResponse> SendWebHookAsync(WebhookWorkItem webHookWorkItem);
Ejemplo n.º 11
0
 public static WebhookFeedEntry CreateErrorEntry(WebhookWorkItem webHookWorkItem, WebhookSendResponse response)
 {
     return(CreateFeedEntry(WebhookFeedEntryType.Error, webHookWorkItem.EventId, response, webHookWorkItem.WebHook));
 }