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));
        }
Example #2
0
        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));
        }
Example #3
0
        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)));
        }
Example #4
0
        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);
        }