private async Task <IHttpActionResult> ProcessWebHook(string webHookReceiver, string id) { IWebHookReceiverManager receiverManager = Configuration.DependencyResolver.GetReceiverManager(); IWebHookReceiver receiver = receiverManager.GetReceiver(webHookReceiver); if (receiver == null) { string msg = string.Format(CultureInfo.CurrentCulture, @"No WebHook receiver is registered with the name '{0}'.", webHookReceiver); Configuration.DependencyResolver.GetLogger().Error(msg); return(NotFound()); } try { string msg = string.Format(CultureInfo.CurrentCulture, @"Processing incoming WebHook request with receiver '{0}' and id '{1}'.", webHookReceiver, id); Configuration.DependencyResolver.GetLogger().Info(msg); HttpResponseMessage response = await receiver.ReceiveAsync(id, RequestContext, Request); return(ResponseMessage(response)); } catch (HttpResponseException rex) { return(ResponseMessage(rex.Response)); } catch (Exception ex) { Exception inner = ex.GetBaseException(); string msg = string.Format(CultureInfo.CurrentCulture, @"WebHook receiver '{0}' could not process WebHook due to error: {1}", webHookReceiver, inner.Message); Configuration.DependencyResolver.GetLogger().Error(msg, inner); throw; } }
private async Task <IHttpActionResult> ProcessWebHook(string webHookReceiver, string id) { IWebHookReceiverManager receiverManager = Configuration.DependencyResolver.GetReceiverManager(); IWebHookReceiver receiver = receiverManager.GetReceiver(webHookReceiver); if (receiver == null) { string msg = string.Format(CultureInfo.CurrentCulture, ReceiverResources.ReceiverController_Unknown, webHookReceiver); Configuration.DependencyResolver.GetLogger().Error(msg); return(NotFound()); } try { string msg = string.Format(CultureInfo.CurrentCulture, ReceiverResources.ReceiverController_Processing, webHookReceiver); Configuration.DependencyResolver.GetLogger().Info(msg); HttpResponseMessage response = await receiver.ReceiveAsync(id, RequestContext, Request); return(ResponseMessage(response)); } catch (HttpResponseException rex) { return(ResponseMessage(rex.Response)); } catch (Exception ex) { ex = ex.GetBaseException(); string msg = string.Format(CultureInfo.CurrentCulture, ReceiverResources.ReceiverController_Failure, webHookReceiver, ex.Message); Configuration.DependencyResolver.GetLogger().Error(msg, ex); HttpResponseMessage response = Request.CreateErrorResponse(HttpStatusCode.InternalServerError, msg, ex); return(ResponseMessage(response)); } }
public async Task <HttpResponseMessage> TryHandle(HttpRequestMessage request, Func <HttpRequestMessage, Task <HttpResponseMessage> > invokeJobFunction) { // First check if there is a registered WebHook Receiver for this request, and if // so use it string route = request.RequestUri.LocalPath.ToLowerInvariant(); IWebHookReceiver receiver = null; string receiverId = null; if (TryParseReceiver(route, out receiver, out receiverId)) { HttpRequestContext context = new HttpRequestContext { Configuration = _httpConfiguration }; request.SetConfiguration(_httpConfiguration); // add the anonymous handler function from above to the request properties // so our custom WebHookHandler can invoke it at the right time request.Properties.Add(WebHookJobFunctionInvokerKey, invokeJobFunction); return(await receiver.ReceiveAsync(receiverId, context, request)); } return(null); }
public async Task <HttpResponseMessage> HandleRequestAsync(FunctionDescriptor function, HttpRequestMessage request, Func <HttpRequestMessage, Task <HttpResponseMessage> > invokeFunction) { // First check if there is a registered WebHook Receiver for this request, and if // so use it HttpBindingMetadata httpFunctionMetadata = (HttpBindingMetadata)function.Metadata.InputBindings.FirstOrDefault(p => p.Type == BindingType.HttpTrigger); string webHookReceiver = httpFunctionMetadata.WebHookType; IWebHookReceiver receiver = null; if (string.IsNullOrEmpty(webHookReceiver) || !_receiverLookup.TryGetValue(webHookReceiver, out receiver)) { // If the function is a not a correctly configured WebHook return 500 return(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError)); } HttpRequestContext context = new HttpRequestContext { Configuration = _httpConfiguration }; request.SetConfiguration(_httpConfiguration); // add the anonymous handler function from above to the request properties // so our custom WebHookHandler can invoke it at the right time request.Properties.Add(AzureFunctionsCallbackKey, invokeFunction); // TODO: Is there a better way? Requests content can't be read multiple // times, so this forces it to buffer await request.Content.ReadAsStringAsync(); string receiverId = function.Name.ToLowerInvariant(); return(await receiver.ReceiveAsync(receiverId, context, request)); }
/// <summary> /// Invokes the Middleware to handle a HttpRequest /// </summary> /// <param name="httpContext">The HttpContext for the Request</param> /// <returns></returns> public async Task Invoke(HttpContext httpContext) { // Get all the Receivers IEnumerable <IWebHookReceiver> receivers = (IEnumerable <IWebHookReceiver>)httpContext.RequestServices.GetService(typeof(IEnumerable <IWebHookReceiver>)); // Find the Matching Receiver and capture the remaining path segment PathString remaining = new PathString(); IWebHookReceiver matchingReceiver = receivers.Where(r => httpContext.Request.Path.StartsWithSegments($"/{r.Name}", out remaining)).FirstOrDefault(); if (matchingReceiver != null) { // If we found a mathing receiver, use it to build a WebHookHandlerContext _logger.LogInformation("WebHooks matched the '{0}' path to the '{1}' receiver by the name '{2}'.", httpContext.Request.Path, matchingReceiver.GetType().FullName, matchingReceiver.Name); WebHookHandlerContext context = await matchingReceiver.ReceiveAsync(remaining, httpContext); if (context != null) { // If the Receiver returned a Context, then find the matching handlers IEnumerable <IWebHookHandler> handlers = (IEnumerable <IWebHookHandler>)httpContext.RequestServices.GetService(typeof(IEnumerable <IWebHookHandler>)); if (handlers != null && handlers.Count() > 0) { // Sort any available handlers IEnumerable <IWebHookHandler> orderedHandlers = handlers.OrderBy(h => h.Order); // Execute each handler in order foreach (IWebHookHandler handler in orderedHandlers) { if (String.IsNullOrWhiteSpace(handler.Receiver) || handler.Receiver.Equals(matchingReceiver.Name, StringComparison.CurrentCultureIgnoreCase)) { _logger.LogInformation("Executing the '{0}' Handler with the Context from the '{1}' Receiver.", handler.GetType().FullName, matchingReceiver.GetType().FullName); await handler.ExecuteAsync(remaining, context); } } } else { _logger.LogWarning("No Handlers were found to process the context from '{0}' Receiver.", matchingReceiver.Name); } } } else { _logger.LogDebug("No Matching Receiver was found."); await _next(httpContext); } }
public async Task <HttpResponseMessage> HandleRequestAsync(FunctionDescriptor function, HttpRequestMessage request, Func <HttpRequestMessage, Task <HttpResponseMessage> > invokeFunction) { // First check if there is a registered WebHook Receiver for this request, and if // so use it var httpTrigger = function.GetTriggerAttributeOrNull <HttpTriggerAttribute>(); string webHookReceiver = httpTrigger.WebHookType; IWebHookReceiver receiver = null; if (string.IsNullOrEmpty(webHookReceiver) || !_receiverLookup.TryGetValue(webHookReceiver, out receiver)) { // The function is not correctly configured. Log an error and return 500 string configurationError = string.Format(CultureInfo.InvariantCulture, "Invalid WebHook configuration. Unable to find a receiver for WebHook type '{0}'", webHookReceiver); function.Invoker.OnError(new FunctionInvocationException(configurationError)); return(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError)); } // if the code value is specified via header rather than query string // promote it to the query string (that's what the WebHook library expects) ApplyHeaderValuesToQuery(request); HttpRequestContext context = new HttpRequestContext { Configuration = _httpConfiguration }; request.SetConfiguration(_httpConfiguration); // add the anonymous handler function from above to the request properties // so our custom WebHookHandler can invoke it at the right time request.Properties.Add(AzureFunctionsCallbackKey, invokeFunction); // Request content can't be read multiple // times, so this forces it to buffer await request.Content.LoadIntoBufferAsync(); string receiverId = function.Name.ToLowerInvariant(); // Get an optional client ID. This information is passed as the receiver ID, allowing // the receiver config to map configuration based on the client ID (primarily used for secret resolution). string clientId = GetClientID(request); string webhookId = $"{receiverId},{clientId}"; return(await receiver.ReceiveAsync(webhookId, context, request)); }
public async Task <HttpResponseMessage> HandleRequestAsync(FunctionDescriptor function, HttpRequestMessage request, Func <HttpRequestMessage, Task <HttpResponseMessage> > invokeFunction) { // First check if there is a registered WebHook Receiver for this request, and if // so use it HttpTriggerBindingMetadata httpFunctionMetadata = (HttpTriggerBindingMetadata)function.Metadata.InputBindings.FirstOrDefault(p => string.Compare("HttpTrigger", p.Type, StringComparison.OrdinalIgnoreCase) == 0); string webHookReceiver = httpFunctionMetadata.WebHookType; IWebHookReceiver receiver = null; if (string.IsNullOrEmpty(webHookReceiver) || !_receiverLookup.TryGetValue(webHookReceiver, out receiver)) { // The function is not correctly configured. Log an error and return 500 string configurationError = string.Format(CultureInfo.InvariantCulture, "Invalid WebHook configuration. Unable to find a receiver for WebHook type '{0}'", webHookReceiver); function.Invoker.OnError(new FunctionInvocationException(configurationError)); return(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError)); } HttpRequestContext context = new HttpRequestContext { Configuration = _httpConfiguration }; request.SetConfiguration(_httpConfiguration); // add the anonymous handler function from above to the request properties // so our custom WebHookHandler can invoke it at the right time request.Properties.Add(AzureFunctionsCallbackKey, invokeFunction); // Request content can't be read multiple // times, so this forces it to buffer await request.Content.LoadIntoBufferAsync(); string receiverId = function.Name.ToLowerInvariant(); // Get an optional client ID. This information is passed as the receiver ID, allowing // the receiver config to map configuration based on the client ID (primarily used for secret resolution). string clientId = GetClientID(request); string webhookId = $"{receiverId},{clientId}"; return(await receiver.ReceiveAsync(webhookId, context, request)); }