internal static void Initialize(ContainerBuilder builder, WebHostSettings settings)
        {
            ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath     = settings.ScriptPath,
                RootLogPath        = settings.LogPath,
                FileLoggingEnabled = true
            };

            // If running on Azure Web App, derive the host ID from the site name
            string hostId = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME");

            if (!String.IsNullOrEmpty(hostId))
            {
                // Truncate to the max host name length if needed
                const int MaximumHostIdLength = 32;
                if (hostId.Length > MaximumHostIdLength)
                {
                    hostId = hostId.Substring(0, MaximumHostIdLength);
                }

                // Trim any trailing - as they can cause problems with queue names
                hostId = hostId.TrimEnd('-');

                scriptHostConfig.HostConfig.HostId = hostId.ToLowerInvariant();
            }

            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig);

            builder.RegisterInstance <WebScriptHostManager>(scriptHostManager);

            SecretManager secretManager = new SecretManager(settings.SecretsPath);

            // Make sure that host secrets get created on startup if they don't exist
            secretManager.GetHostSecrets();
            builder.RegisterInstance <SecretManager>(secretManager);

            WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager);

            builder.RegisterInstance <WebHookReceiverManager>(webHookReceiverManager);

            if (!settings.IsSelfHost)
            {
                HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct));
            }
            else
            {
                Task.Run(() => scriptHostManager.RunAndBlock());
            }
        }
Пример #2
0
        public void GeneratedMethods_WithOutParams_DoNotCauseDeadlocks()
        {
            var traceWriter = new TestTraceWriter(TraceLevel.Verbose);

            ScriptHostConfiguration config = new ScriptHostConfiguration()
            {
                RootScriptPath = @"TestScripts\FunctionGeneration",
                TraceWriter    = traceWriter
            };

            using (var manager = new WebScriptHostManager(config))
            {
                Thread runLoopThread = new Thread(_ =>
                {
                    manager.RunAndBlock(CancellationToken.None);
                });
                runLoopThread.IsBackground = true;
                runLoopThread.Start();

                while (!manager.IsRunning)
                {
                    Thread.Sleep(100);
                }

                FunctionDescriptor function = manager.GetHttpFunctionOrNull(new Uri("http://localhost/api/httptrigger-csharp"));
                var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/httptrigger-csharp");

                SynchronizationContext currentContext = SynchronizationContext.Current;
                var resetEvent = new ManualResetEventSlim();

                try
                {
                    var requestThread = new Thread(() =>
                    {
                        var context = new SingleThreadSynchronizationContext();
                        SynchronizationContext.SetSynchronizationContext(context);

                        manager.HandleRequestAsync(function, request, CancellationToken.None)
                        .ContinueWith(task => resetEvent.Set());

                        Thread.Sleep(500);
                        context.Run();
                    });

                    requestThread.IsBackground = true;
                    requestThread.Start();

                    bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10));

                    requestThread.Abort();

                    Assert.True(threadSignaled, "Thread execution did not complete");
                }
                finally
                {
                    SynchronizationContext.SetSynchronizationContext(currentContext);
                    manager.Stop();
                }
            }
        }
        private async Task <WebScriptHostManager> CreateAndStartWebScriptHostManager(TraceWriter traceWriter)
        {
            var functions = new Collection <string> {
                "TimeoutToken"
            };

            ScriptHostConfiguration config = new ScriptHostConfiguration()
            {
                RootScriptPath  = $@"TestScripts\CSharp",
                TraceWriter     = traceWriter,
                FileLoggingMode = FileLoggingMode.Always,
                Functions       = functions,
                FunctionTimeout = TimeSpan.FromSeconds(3)
            };

            var mockEventManager = new Mock <IScriptEventManager>();
            var mockRouter       = new Mock <IWebJobsRouter>();
            var manager          = new WebScriptHostManager(
                config,
                new TestSecretManagerFactory(),
                mockEventManager.Object,
                ScriptSettingsManager.Instance,
                new WebHostSettings {
                SecretsPath = _secretsDirectory.Path
            },
                mockRouter.Object);

            Task task = Task.Run(() => { manager.RunAndBlock(); });
            await TestHelpers.Await(() => manager.State == ScriptHostState.Running);

            return(manager);
        }
        internal static void Initialize(ContainerBuilder builder, WebHostSettings settings)
        {
            ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath = settings.ScriptPath,
                RootLogPath = settings.LogPath,
                FileLoggingEnabled = true
            };

            // If running on Azure Web App, derive the host ID from the site name
            string hostId = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME");
            if (!String.IsNullOrEmpty(hostId))
            {
                // Truncate to the max host name length if needed
                const int MaximumHostIdLength = 32;
                if (hostId.Length > MaximumHostIdLength)
                {
                    hostId = hostId.Substring(0, MaximumHostIdLength);
                }

                // Trim any trailing - as they can cause problems with queue names
                hostId = hostId.TrimEnd('-');

                scriptHostConfig.HostConfig.HostId = hostId.ToLowerInvariant();
            }

            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig);
            builder.RegisterInstance<WebScriptHostManager>(scriptHostManager);

            SecretManager secretManager = new SecretManager(settings.SecretsPath);
            // Make sure that host secrets get created on startup if they don't exist
            secretManager.GetHostSecrets();
            builder.RegisterInstance<SecretManager>(secretManager);

            WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager);
            builder.RegisterInstance<WebHookReceiverManager>(webHookReceiverManager);

            if (!settings.IsSelfHost)
            {
                HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct));
            }
            else
            {
                Task.Run(() => scriptHostManager.RunAndBlock());
            }
        }
Пример #5
0
        public async Task EmptyHost_StartsSuccessfully()
        {
            await _fixture.InitializationTask;

            string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString());

            Directory.CreateDirectory(functionTestDir);

            // important for the repro that these directories no not exist
            string logDir     = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString());
            string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString());

            JObject hostConfig = new JObject
            {
                { "id", "123456" }
            };

            File.WriteAllText(Path.Combine(functionTestDir, ScriptConstants.HostMetadataFileName), hostConfig.ToString());

            ScriptHostConfiguration config = new ScriptHostConfiguration
            {
                RootScriptPath  = functionTestDir,
                RootLogPath     = logDir,
                FileLoggingMode = FileLoggingMode.Always
            };
            string             connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage);
            ISecretsRepository repository       = new BlobStorageSecretsRepository(secretsDir, connectionString, "EmptyHost_StartsSuccessfully");
            ISecretManager     secretManager    = new SecretManager(_settingsManager, repository, null);
            WebHostSettings    webHostSettings  = new WebHostSettings();

            webHostSettings.SecretsPath = _secretsDirectory.Path;
            var               mockEventManager = new Mock <IScriptEventManager>();
            IWebJobsRouter    router           = _fixture.CreateRouter();
            ScriptHostManager hostManager      = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), mockEventManager.Object, _settingsManager, webHostSettings, router, NullLoggerFactory.Instance);

            Task runTask = Task.Run(() => hostManager.RunAndBlock());

            await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000);

            hostManager.Stop();
            Assert.Equal(ScriptHostState.Default, hostManager.State);

            // give some time for the logs to be flushed fullly
            await Task.Delay(FileWriter.LogFlushIntervalMs * 3);

            string hostLogFilePath = Directory.EnumerateFiles(Path.Combine(logDir, "Host")).Single();
            string hostLogs        = File.ReadAllText(hostLogFilePath);

            Assert.Contains("Generating 0 job function(s)", hostLogs);
            Assert.Contains("No job functions found.", hostLogs);
            Assert.Contains("Job host started", hostLogs);
            Assert.Contains("Job host stopped", hostLogs);
        }
        public async Task MultipleHostRestarts()
        {
            string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString());

            Directory.CreateDirectory(functionTestDir);
            string logDir     = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString());
            string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString());

            ScriptHostConfiguration config = new ScriptHostConfiguration
            {
                RootLogPath     = logDir,
                RootScriptPath  = functionTestDir,
                FileLoggingMode = FileLoggingMode.Always,
            };

            ISecretsRepository repository      = new FileSystemSecretsRepository(_secretsDirectory.Path);
            SecretManager      secretManager   = new SecretManager(_settingsManager, repository, NullTraceWriter.Instance, null);
            WebHostSettings    webHostSettings = new WebHostSettings();

            webHostSettings.SecretsPath = _secretsDirectory.Path;

            var mockEventManager = new Mock <IScriptEventManager>();
            var factoryMock      = new Mock <IScriptHostFactory>();
            int count            = 0;

            factoryMock.Setup(p => p.Create(It.IsAny <IScriptHostEnvironment>(), It.IsAny <IScriptEventManager>(), _settingsManager, config)).Callback(() =>
            {
                count++;
            }).Throws(new Exception("Kaboom!"));

            ScriptHostManager hostManager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), mockEventManager.Object,
                                                                     _settingsManager, webHostSettings, factoryMock.Object);

            Task runTask = Task.Run(() => hostManager.RunAndBlock());

            await TestHelpers.Await(() =>
            {
                return(count > 3);
            });

            hostManager.Stop();
            Assert.Equal(ScriptHostState.Default, hostManager.State);

            // regression test: previously on multiple restarts we were recomposing
            // the writer on each restart, resulting in a nested chain of writers
            // increasing on each restart
            Assert.Equal(typeof(SystemTraceWriter), config.TraceWriter.GetType());
        }
        internal static void Initialize(ContainerBuilder builder)
        {
            string logFilePath;
            string scriptRootPath;
            string secretsPath;
            string home    = Environment.GetEnvironmentVariable("HOME");
            bool   isLocal = string.IsNullOrEmpty(home);

            if (isLocal)
            {
                // we're running locally
                scriptRootPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"..\..\sample");
                logFilePath    = Path.Combine(Path.GetTempPath(), @"Functions");
                secretsPath    = HttpContext.Current.Server.MapPath("~/App_Data/Secrets");
            }
            else
            {
                // we're running in Azure
                scriptRootPath = Path.Combine(home, @"site\wwwroot");
                logFilePath    = Path.Combine(home, @"LogFiles\Application\Functions");
                secretsPath    = Path.Combine(home, @"data\Functions\secrets");
            }

            ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath     = scriptRootPath,
                RootLogPath        = logFilePath,
                FileLoggingEnabled = true
            };
            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig);

            builder.RegisterInstance <WebScriptHostManager>(scriptHostManager);

            SecretManager secretManager = new SecretManager(secretsPath);

            builder.RegisterInstance <SecretManager>(secretManager);

            WebHookReceiverManager webHookRecieverManager = new WebHookReceiverManager(secretManager);

            builder.RegisterInstance <WebHookReceiverManager>(webHookRecieverManager);

            Task.Run(() => scriptHostManager.RunAndBlock(CancellationToken.None));
        }
        internal static void Initialize(ContainerBuilder builder)
        {
            string logFilePath;
            string scriptRootPath;
            string secretsPath;
            string home = Environment.GetEnvironmentVariable("HOME");
            bool isLocal = string.IsNullOrEmpty(home);
            if (isLocal)
            {
                // we're running locally
                scriptRootPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"..\..\sample");
                logFilePath = Path.Combine(Path.GetTempPath(), @"Functions");
                secretsPath = HttpContext.Current.Server.MapPath("~/App_Data/Secrets");
            }
            else
            {
                // we're running in Azure
                scriptRootPath = Path.Combine(home, @"site\wwwroot");
                logFilePath = Path.Combine(home, @"LogFiles\Application\Functions");
                secretsPath = Path.Combine(home, @"data\Functions\secrets");
            }

            ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath = scriptRootPath,
                RootLogPath = logFilePath,
                FileLoggingEnabled = true
            };
            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig);
            builder.RegisterInstance<WebScriptHostManager>(scriptHostManager);

            SecretManager secretManager = new SecretManager(secretsPath);
            builder.RegisterInstance<SecretManager>(secretManager);

            WebHookReceiverManager webHookRecieverManager = new WebHookReceiverManager(secretManager);
            builder.RegisterInstance<WebHookReceiverManager>(webHookRecieverManager);

            Task.Run(() => scriptHostManager.RunAndBlock(CancellationToken.None));
        }
Пример #9
0
        internal async Task GeneratedMethods_WithOutParams_DoNotCauseDeadlocks(string fixture)
        {
            var traceWriter = new TestTraceWriter(TraceLevel.Verbose);

            ScriptHostConfiguration config = new ScriptHostConfiguration()
            {
                RootScriptPath = @"TestScripts\FunctionGeneration",
                TraceWriter    = traceWriter
            };

            string             secretsPath     = Path.Combine(Path.GetTempPath(), @"FunctionTests\Secrets");
            ISecretsRepository repository      = new FileSystemSecretsRepository(secretsPath);
            WebHostSettings    webHostSettings = new WebHostSettings();

            webHostSettings.SecretsPath = secretsPath;

            var secretManager = new SecretManager(SettingsManager, repository, NullTraceWriter.Instance);

            using (var manager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), SettingsManager, webHostSettings))
            {
                Thread runLoopThread = new Thread(_ =>
                {
                    manager.RunAndBlock(CancellationToken.None);
                });
                runLoopThread.IsBackground = true;
                runLoopThread.Start();

                await TestHelpers.Await(() =>
                {
                    return(manager.State == ScriptHostState.Running);
                });

                var request = new HttpRequestMessage(HttpMethod.Get, String.Format("http://localhost/api/httptrigger-{0}", fixture));
                FunctionDescriptor function = manager.GetHttpFunctionOrNull(request);

                SynchronizationContext currentContext = SynchronizationContext.Current;
                var resetEvent = new ManualResetEventSlim();

                try
                {
                    var requestThread = new Thread(() =>
                    {
                        var context = new SingleThreadSynchronizationContext();
                        SynchronizationContext.SetSynchronizationContext(context);

                        manager.HandleRequestAsync(function, request, CancellationToken.None)
                        .ContinueWith(task => resetEvent.Set());

                        Thread.Sleep(500);
                        context.Run();
                    });

                    requestThread.IsBackground = true;
                    requestThread.Start();

                    bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10));

                    requestThread.Abort();

                    Assert.True(threadSignaled, "Thread execution did not complete");
                }
                finally
                {
                    SynchronizationContext.SetSynchronizationContext(currentContext);
                    manager.Stop();
                }
            }
        }