public async Task RegisterRoute(Uri route, ParameterInfo triggerParameter, ITriggeredFunctionExecutor executor) { await EnsureServerOpen(); string routeKey = route.LocalPath.ToLowerInvariant(); if (_functions.ContainsKey(routeKey)) { throw new InvalidOperationException(string.Format("Duplicate route detected. There is already a route registered for '{0}'", routeKey)); } _functions.AddOrUpdate(routeKey, executor, (k, v) => { return(executor); }); WebHookTriggerAttribute attribute = triggerParameter.GetCustomAttribute <WebHookTriggerAttribute>(); IWebHookReceiver receiver = null; string receiverId = string.Empty; string receiverLog = string.Empty; if (attribute != null && _webHookReceiverManager.TryParseReceiver(route.LocalPath, out receiver, out receiverId)) { receiverLog = string.Format(" (Receiver: '{0}', Id: '{1}')", receiver.Name, receiverId); } MethodInfo method = (MethodInfo)triggerParameter.Member; string methodName = string.Format("{0}.{1}", method.DeclaringType, method.Name); _trace.Verbose(string.Format("WebHook route '{0}' registered for function '{1}'{2}", route.LocalPath, methodName, receiverLog)); }
internal static Uri FormatWebHookUri(Uri baseAddress, WebHookTriggerAttribute attribute, ParameterInfo parameter) { // build the full route from the base route string subRoute; if (!string.IsNullOrEmpty(attribute.Route)) { subRoute = attribute.Route; } else { MethodInfo method = (MethodInfo)parameter.Member; subRoute = string.Format("{0}/{1}", method.DeclaringType.Name, method.Name); } return(new Uri(baseAddress, subRoute)); }
public Task <ITriggerBinding> TryCreateAsync(TriggerBindingProviderContext context) { if (context == null) { throw new ArgumentNullException("context"); } ParameterInfo parameter = context.Parameter; WebHookTriggerAttribute attribute = parameter.GetCustomAttribute <WebHookTriggerAttribute>(inherit: false); if (attribute == null) { return(Task.FromResult <ITriggerBinding>(null)); } // Can bind to user types, HttpRequestMessage, WebHookContext, and all the Read // Types supported by StreamValueBinder IEnumerable <Type> supportedTypes = StreamValueBinder.GetSupportedTypes(FileAccess.Read) .Union(new Type[] { typeof(HttpRequestMessage), typeof(WebHookContext) }); bool isSupportedTypeBinding = ValueBinder.MatchParameterType(parameter, supportedTypes); bool isUserTypeBinding = !isSupportedTypeBinding && WebHookTriggerBinding.IsValidUserType(parameter.ParameterType); if (!isSupportedTypeBinding && !isUserTypeBinding) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Can't bind WebHookTriggerAttribute to type '{0}'.", parameter.ParameterType)); } if (!isUserTypeBinding && attribute.FromUri) { throw new InvalidOperationException("'FromUri' can only be set to True when binding to custom Types."); } // Validate route format if (!string.IsNullOrEmpty(attribute.Route)) { string[] routeSegements = attribute.Route.Split('/'); if (routeSegements.Length > 2) { throw new InvalidOperationException("WebHook routes can only have a maximum of two segments."); } } return(Task.FromResult <ITriggerBinding>(new WebHookTriggerBinding(_dispatcher, context.Parameter, isUserTypeBinding, attribute))); }
public WebHookTriggerBinding(WebHookDispatcher dispatcher, ParameterInfo parameter, bool isUserTypeBinding, WebHookTriggerAttribute attribute) { _dispatcher = dispatcher; _parameter = parameter; _isUserTypeBinding = isUserTypeBinding; _attribute = attribute; if (_isUserTypeBinding) { // Create the BindingDataProvider from the user Type. The BindingDataProvider // is used to define the binding parameters that the binding exposes to other // bindings (i.e. the properties of the POCO can be bound to by other bindings). // It is also used to extract the binding data from an instance of the Type. _bindingDataProvider = BindingDataProvider.FromType(parameter.ParameterType); } Uri baseAddress = new Uri(string.Format("http://localhost:{0}", dispatcher.Port)); _route = FormatWebHookUri(baseAddress, attribute, parameter); }