Exemplo n.º 1
0
        public async Task ProcessRequest_MaxParallelism_RequestsAreThrottled()
        {
            int maxParallelism = 3;
            int count          = 0;
            Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > process = async(req, ct) =>
            {
                if (Interlocked.Increment(ref count) > maxParallelism)
                {
                    throw new Exception("Kaboom!");
                }

                await Task.Delay(100);

                Interlocked.Decrement(ref count);

                return(new HttpResponseMessage(HttpStatusCode.OK));
            };
            var config = new HttpExtensionConfiguration
            {
                MaxConcurrentRequests = maxParallelism
            };
            var manager = new HttpRequestManager(config, _traceWriter);

            // expect all requests to succeed
            var tasks = new List <Task <HttpResponseMessage> >();

            for (int i = 0; i < 20; i++)
            {
                var request = new HttpRequestMessage();
                tasks.Add(manager.ProcessRequestAsync(request, process, CancellationToken.None));
            }
            await Task.WhenAll(tasks);

            Assert.True(tasks.All(p => p.Result.StatusCode == HttpStatusCode.OK));
        }
        public override void Initialize()
        {
            // Apply Blobs configuration
            // TODO: FACAVAL - Follow up on TEMP comment below
            Config.Blobs.CentralizedPoisonQueue = true;   // TEMP : In the next release we'll remove this and accept the core SDK default
            var    configSection = (JObject)Metadata["blobs"];
            JToken value         = null;

            if (configSection != null)
            {
                if (configSection.TryGetValue("centralizedPoisonQueue", out value))
                {
                    Config.Blobs.CentralizedPoisonQueue = (bool)value;
                }
            }

            // apply http configuration configuration
            configSection = (JObject)Metadata["http"];
            HttpExtensionConfiguration httpConfig = null;

            if (configSection != null)
            {
                httpConfig = configSection.ToObject <HttpExtensionConfiguration>();
            }
            httpConfig             = httpConfig ?? new HttpExtensionConfiguration();
            httpConfig.SetResponse = HttpBinding.SetResponse;

            Config.UseScriptExtensions();
            Config.UseHttp(httpConfig);
        }
        public override void Initialize()
        {
            // Apply Blobs configuration
            var    configSection = (JObject)Metadata["blobs"];
            JToken value         = null;

            if (configSection != null)
            {
                if (configSection.TryGetValue("centralizedPoisonQueue", out value))
                {
                    Config.Blobs.CentralizedPoisonQueue = (bool)value;
                }
            }

            // apply http configuration configuration
            configSection = (JObject)Metadata["http"];
            HttpExtensionConfiguration httpConfig = null;

            if (configSection != null)
            {
                httpConfig = configSection.ToObject <HttpExtensionConfiguration>();
            }
            httpConfig             = httpConfig ?? new HttpExtensionConfiguration();
            httpConfig.SetResponse = HttpBinding.SetResponse;

            Config.UseScriptExtensions();
            Config.UseHttp(httpConfig);
        }
Exemplo n.º 4
0
        public async Task ProcessRequest_HostIsOverloaded_CustomRejectAction()
        {
            bool        rejectOverrideCalled = false;
            var         config            = new HttpExtensionConfiguration();
            Func <bool> rejectAllRequests = () =>
            {
                return(true);
            };
            Func <HttpRequestMessage, HttpResponseMessage> rejectRequest = (req) =>
            {
                rejectOverrideCalled = true;
                return(new HttpResponseMessage(HttpStatusCode.ServiceUnavailable));
            };

            Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > process = (req, ct) =>
            {
                return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
            };
            var manager = new TestHttpRequestManager(config, _traceWriter, rejectAllRequests, rejectRequest);

            var request  = new HttpRequestMessage();
            var response = await manager.ProcessRequestAsync(request, process, CancellationToken.None);

            Assert.True(rejectOverrideCalled);
            Assert.Equal(HttpStatusCode.ServiceUnavailable, response.StatusCode);
        }
Exemplo n.º 5
0
        public async Task ProcessRequest_HostIsOverloaded_RequestsAreRejected()
        {
            bool        rejectRequests    = false;
            var         config            = new HttpExtensionConfiguration();
            Func <bool> rejectAllRequests = () =>
            {
                return(rejectRequests);
            };

            Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > process = async(req, ct) =>
            {
                await Task.Delay(100);

                return(new HttpResponseMessage(HttpStatusCode.OK));
            };
            var manager = new TestHttpRequestManager(config, _traceWriter, rejectAllRequests);

            var tasks = new List <Task <HttpResponseMessage> >();

            for (int i = 0; i < 10; i++)
            {
                if (i == 7)
                {
                    rejectRequests = true;
                }
                var request = new HttpRequestMessage();
                tasks.Add(manager.ProcessRequestAsync(request, process, CancellationToken.None));
            }
            await Task.WhenAll(tasks);

            Assert.Equal(7, tasks.Count(p => p.Result.StatusCode == HttpStatusCode.OK));
            Assert.Equal(3, tasks.Count(p => p.Result.StatusCode == (HttpStatusCode)429));
        }
        private void InitializeHttp()
        {
            // get the registered http configuration from the extension registry
            var extensions = Instance.ScriptConfig.HostConfig.GetService <IExtensionRegistry>();
            HttpExtensionConfiguration httpConfig = extensions.GetExtensions <IExtensionConfigProvider>().OfType <HttpExtensionConfiguration>().Single();

            InitializeHttpFunctions(Instance.Functions, httpConfig);
        }
 public WebScriptHostRequestManagerTests()
 {
     _metricsLogger      = new Mock <IMetricsLogger>(MockBehavior.Strict);
     _performanceManager = new Mock <HostPerformanceManager>(MockBehavior.Strict, new object[] { new ScriptSettingsManager(), new HostHealthMonitorConfiguration() });
     _httpConfig         = new HttpExtensionConfiguration();
     _traceWriter        = new TestTraceWriter(TraceLevel.Verbose);
     _requestManager     = new WebScriptHostRequestManager(_httpConfig, _performanceManager.Object, _metricsLogger.Object, _traceWriter, 1);
     _functionDescriptor = new FunctionDescriptor("Test", null, null, new Collection <ParameterDescriptor>(), null, null, null);
 }
        public HttpTriggerEndToEndTests()
        {
            var httpConfig = new HttpExtensionConfiguration();

            httpConfig.SetResponse = SetResultHook;
            _config = new JobHostConfiguration
            {
                TypeLocator = new ExplicitTypeLocator(typeof(TestFunctions))
            };
            _config.UseHttp(httpConfig);
            _host = new JobHost(_config);
        }
        public HttpTriggerEndToEndTests()
        {
            var httpConfig = new HttpExtensionConfiguration();

            httpConfig.SetResponse = SetResultHook;
            _config = new JobHostConfiguration
            {
                TypeLocator = new ExplicitTypeLocator(typeof(TestFunctions))
            };
            _config.UseHttp(httpConfig);
            _config.UseHttp();
            _config.AddService <IWebJobsExceptionHandler>(new TestExceptionHandler());
            _host = new JobHost(_config);
        }
        public async Task ProcessRequest_MaxOutstandingRequestsExceeded_RequestsAreRejected()
        {
            int maxQueueLength = 10;
            Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > process = async(req, ct) =>
            {
                await Task.Delay(100);

                return(new HttpResponseMessage(HttpStatusCode.OK));
            };
            var config = new HttpExtensionConfiguration
            {
                MaxOutstandingRequests = maxQueueLength,
                MaxConcurrentRequests  = 1
            };
            var manager = new HttpRequestManager(config, _loggerFactory);

            // expect requests past the threshold to be rejected
            var tasks = new List <Task <HttpResponseMessage> >();

            for (int i = 0; i < 25; i++)
            {
                var request = new HttpRequestMessage();
                tasks.Add(manager.ProcessRequestAsync(request, process, CancellationToken.None));
            }
            await Task.WhenAll(tasks);

            int countSuccess = tasks.Count(p => p.Result.StatusCode == HttpStatusCode.OK);

            Assert.Equal(maxQueueLength, countSuccess);
            int rejectCount = 25 - countSuccess;

            Assert.Equal(rejectCount, tasks.Count(p => p.Result.StatusCode == (HttpStatusCode)429));

            IEnumerable <LogMessage> logMessages = _loggerProvider.GetAllLogMessages();

            Assert.Equal(rejectCount, logMessages.Count());
            Assert.True(logMessages.All(p => string.Compare("Http request queue limit of 10 has been exceeded.", p.FormattedMessage) == 0));

            // send a number of requests not exceeding the limit
            // expect all to succeed
            tasks = new List <Task <HttpResponseMessage> >();
            for (int i = 0; i < maxQueueLength; i++)
            {
                var request = new HttpRequestMessage();
                tasks.Add(manager.ProcessRequestAsync(request, process, CancellationToken.None));
            }
            await Task.WhenAll(tasks);

            Assert.True(tasks.All(p => p.Result.StatusCode == HttpStatusCode.OK));
        }
Exemplo n.º 11
0
        /// <summary>
        /// Enables use of Http extensions
        /// </summary>
        /// <param name="config">The <see cref="JobHostConfiguration"/> to configure.</param>
        /// <param name="httpConfig">The <see cref="HttpExtensionConfiguration"/> to use.</param>
        public static void UseHttp(this JobHostConfiguration config, HttpExtensionConfiguration httpConfig = null)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            if (httpConfig == null)
            {
                httpConfig = new HttpExtensionConfiguration();
            }

            config.RegisterExtensionConfigProvider(httpConfig);
        }
Exemplo n.º 12
0
        public async Task ProcessRequest_NoThrottle_DispatchesDirectly()
        {
            var response = new HttpResponseMessage(HttpStatusCode.OK);
            Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > process = (req, ct) =>
            {
                return(Task.FromResult(response));
            };
            var config  = new HttpExtensionConfiguration();
            var manager = new HttpRequestManager(config, _traceWriter);

            var request = new HttpRequestMessage();
            var result  = await manager.ProcessRequestAsync(request, process, CancellationToken.None);

            Assert.Same(response, result);
        }
Exemplo n.º 13
0
        public async Task ProcessRequest_PropigatesExceptions()
        {
            var ex = new Exception("Kaboom!");
            Func <HttpRequestMessage, CancellationToken, Task <HttpResponseMessage> > process = (req, ct) =>
            {
                throw ex;
            };
            var config = new HttpExtensionConfiguration
            {
                MaxOutstandingRequests = 10,
                MaxConcurrentRequests  = 5
            };
            var manager = new HttpRequestManager(config, _traceWriter);

            var resultEx = await Assert.ThrowsAsync <Exception>(async() =>
            {
                var request = new HttpRequestMessage();
                await manager.ProcessRequestAsync(request, process, CancellationToken.None);
            });

            Assert.Same(ex, resultEx);
        }
        private void InitializeHttpFunctions(IEnumerable <FunctionDescriptor> functions, HttpExtensionConfiguration httpConfig)
        {
            _router.ClearRoutes();

            // TODO: FACAVAL Instantiation of the ScriptRouteHandler should be cleaned up
            ILoggerFactory      loggerFactory = _config.HostConfig.LoggerFactory;
            WebJobsRouteBuilder routesBuilder = _router.CreateBuilder(new ScriptRouteHandler(loggerFactory, this, _settingsManager), httpConfig.RoutePrefix);

            // Proxies do not honor the route prefix defined in host.json
            WebJobsRouteBuilder proxiesRoutesBuilder = _router.CreateBuilder(new ScriptRouteHandler(loggerFactory, this, _settingsManager), routePrefix: null);

            foreach (var function in functions)
            {
                var httpTrigger = function.GetTriggerAttributeOrNull <HttpTriggerAttribute>();
                if (httpTrigger != null)
                {
                    var constraints = new RouteValueDictionary();
                    if (httpTrigger.Methods != null)
                    {
                        constraints.Add("httpMethod", new HttpMethodRouteConstraint(httpTrigger.Methods));
                    }

                    string route = httpTrigger.Route;

                    if (string.IsNullOrEmpty(route))
                    {
                        route = function.Name;
                    }

                    WebJobsRouteBuilder builder = function.Metadata.IsProxy ? proxiesRoutesBuilder : routesBuilder;
                    builder.MapFunctionRoute(function.Metadata.Name, route, constraints, function.Metadata.Name);
                }
            }

            // Proxy routes will take precedence over http trigger functions
            // so they will be added first to the router.
            if (proxiesRoutesBuilder.Count > 0)
            {
                _router.AddFunctionRoute(proxiesRoutesBuilder.Build());
            }

            if (routesBuilder.Count > 0)
            {
                _router.AddFunctionRoute(routesBuilder.Build());
            }
        }
Exemplo n.º 15
0
        private void InitializeHttpFunctions(IEnumerable <FunctionDescriptor> functions, HttpExtensionConfiguration httpConfig)
        {
            // we must initialize the route factory here AFTER full configuration
            // has been resolved so we apply any route prefix customizations
            var functionHttpRouteFactory = new HttpRouteFactory(httpConfig.RoutePrefix);

            // Proxies do not honor the route prefix defined in host.json
            var proxyHttpRouteFactory = new HttpRouteFactory(string.Empty);

            _httpFunctions = new Dictionary <IHttpRoute, FunctionDescriptor>();
            _httpRoutes    = new HttpRouteCollection();

            // Proxy routes will take precedence over http trigger functions and http trigger
            // routes so they will be added first to the list of http routes.
            var orderdFunctions = functions.OrderBy(f => f.Metadata.IsProxy ? 0 : 1);

            foreach (var function in orderdFunctions)
            {
                var httpTrigger = function.GetTriggerAttributeOrNull <HttpTriggerAttribute>();
                if (httpTrigger != null)
                {
                    IHttpRoute httpRoute = null;
                    IEnumerable <HttpMethod> httpMethods = null;
                    if (httpTrigger.Methods != null)
                    {
                        httpMethods = httpTrigger.Methods.Select(p => new HttpMethod(p)).ToArray();
                    }
                    var httpRouteFactory = function.Metadata.IsProxy ? proxyHttpRouteFactory : functionHttpRouteFactory;
                    if (httpRouteFactory.TryAddRoute(function.Metadata.Name, httpTrigger.Route, httpMethods, _httpRoutes, out httpRoute))
                    {
                        _httpFunctions.Add(httpRoute, function);
                    }
                }
            }
        }
        private void InitializeHttpFunctions(IEnumerable <FunctionDescriptor> functions, HttpExtensionConfiguration httpConfig)
        {
            // we must initialize the route factory here AFTER full configuration
            // has been resolved so we apply any route prefix customizations
            var httpRouteFactory = new HttpRouteFactory(httpConfig.RoutePrefix);

            _httpFunctions = new Dictionary <IHttpRoute, FunctionDescriptor>();
            _httpRoutes    = new HttpRouteCollection();

            foreach (var function in functions)
            {
                var httpTrigger = function.GetTriggerAttributeOrNull <HttpTriggerAttribute>();
                if (httpTrigger != null)
                {
                    IHttpRoute httpRoute = null;
                    IEnumerable <HttpMethod> httpMethods = null;
                    if (httpTrigger.Methods != null)
                    {
                        httpMethods = httpTrigger.Methods.Select(p => new HttpMethod(p)).ToArray();
                    }
                    if (httpRouteFactory.TryAddRoute(function.Metadata.Name, httpTrigger.Route, httpMethods, _httpRoutes, out httpRoute))
                    {
                        _httpFunctions.Add(httpRoute, function);
                    }
                }
            }
        }
Exemplo n.º 17
0
 public WebScriptHostRequestManager(HttpExtensionConfiguration config, HostPerformanceManager performanceManager, IMetricsLogger metricsLogger, TraceWriter traceWriter, int performanceCheckPeriodSeconds = 15) : base(config, traceWriter)
 {
     _performanceManager            = performanceManager;
     _metricsLogger                 = metricsLogger;
     _performanceCheckPeriodSeconds = performanceCheckPeriodSeconds;
 }
Exemplo n.º 18
0
 public TestHttpRequestManager(HttpExtensionConfiguration config, TraceWriter traceWriter, Func <bool> rejectAllRequests = null, Func <HttpRequestMessage, HttpResponseMessage> rejectRequest = null) : base(config, traceWriter)
 {
     _rejectAllRequests = rejectAllRequests;
     _rejectRequest     = rejectRequest;
 }