private static WebHostSettings GetDefaultSettings(ScriptSettingsManager settingsManager)
        {
            WebHostSettings settings = new WebHostSettings();

            string home = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath);
            bool isLocal = string.IsNullOrEmpty(home);
            if (isLocal)
            {
                settings.ScriptPath = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebJobsScriptRoot);
                settings.LogPath = Path.Combine(Path.GetTempPath(), @"Functions");
                settings.SecretsPath = HttpContext.Current.Server.MapPath("~/App_Data/Secrets");
            }
            else
            {
                // we're running in Azure
                settings.ScriptPath = Path.Combine(home, @"site\wwwroot");
                settings.LogPath = Path.Combine(home, @"LogFiles\Application\Functions");
                settings.SecretsPath = Path.Combine(home, @"data\Functions\secrets");
            }

            if (string.IsNullOrEmpty(settings.ScriptPath))
            {
                throw new InvalidOperationException("Unable to determine function script root directory.");
            }

            return settings;
        }
        private void EnsureInitialized(WebHostSettings settings)
        {
            // standby mode can only change from true to false
            // When standby mode changes, we reset all instances
            var standbyMode = WebScriptHostManager.InStandbyMode;

            if (!standbyMode)
            {
                if (_activeHostManager == null)
                {
                    _activeScriptHostConfig = CreateScriptHostConfiguration(settings);

                    _activeHostManager     = new WebScriptHostManager(_activeScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, settings);
                    _activeReceiverManager = new WebHookReceiverManager(_activeHostManager.SecretManager);

                    _standbyHostManager?.Dispose();
                    _standbyReceiverManager?.Dispose();

                    _standbyScriptHostConfig = null;
                    _standbyHostManager      = null;
                    _standbyReceiverManager  = null;
                    _settingsManager.Reset();
                }
            }
            else
            {
                if (_standbyHostManager == null)
                {
                    _standbyScriptHostConfig = CreateScriptHostConfiguration(settings);

                    _standbyHostManager     = new WebScriptHostManager(_standbyScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, settings);
                    _standbyReceiverManager = new WebHookReceiverManager(_standbyHostManager.SecretManager);
                }
            }
        }
Example #3
0
        internal static WebHostSettings CreateDefault(ScriptSettingsManager settingsManager)
        {
            WebHostSettings settings = new WebHostSettings
            {
                IsSelfHost = !settingsManager.IsAzureEnvironment
            };

            if (settingsManager.IsAzureEnvironment)
            {
                string home = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath);
                settings.ScriptPath  = Path.Combine(home, @"site\wwwroot");
                settings.LogPath     = Path.Combine(home, @"LogFiles\Application\Functions");
                settings.SecretsPath = Path.Combine(home, @"data\Functions\secrets");
            }
            else
            {
                settings.ScriptPath  = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebJobsScriptRoot);
                settings.LogPath     = Path.Combine(Path.GetTempPath(), @"Functions");
                settings.SecretsPath = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/Secrets");
            }

            if (string.IsNullOrEmpty(settings.ScriptPath))
            {
                throw new InvalidOperationException("Unable to determine function script root directory.");
            }

            return(settings);
        }
        internal static WebHostSettings CreateDefault(ScriptSettingsManager settingsManager)
        {
            WebHostSettings settings = new WebHostSettings
            {
                IsSelfHost = !settingsManager.IsAppServiceEnvironment && !settingsManager.IsLinuxContainerEnvironment
            };

            if (settingsManager.IsAppServiceEnvironment)
            {
                // Running in App Service
                string home = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath);
                settings.ScriptPath   = Path.Combine(home, "site", "wwwroot");
                settings.LogPath      = Path.Combine(home, "LogFiles", "Application", "Functions");
                settings.SecretsPath  = Path.Combine(home, "data", "Functions", "secrets");
                settings.TestDataPath = Path.Combine(home, "data", "Functions", "sampledata");
            }
            else
            {
                // Local hosting or Linux container scenarios
                settings.ScriptPath   = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebJobsScriptRoot);
                settings.LogPath      = Path.Combine(Path.GetTempPath(), @"Functions");
                settings.TestDataPath = Path.Combine(Path.GetTempPath(), @"FunctionsData");

                // TODO: Revisit. We'll likely have to take an instance of an IHostingEnvironment here
                settings.SecretsPath = Path.Combine(AppContext.BaseDirectory, "Secrets");
            }

            if (string.IsNullOrEmpty(settings.ScriptPath))
            {
                throw new InvalidOperationException("Unable to determine function script root directory.");
            }

            return(settings);
        }
        public void GetHttpFunctionOrNull_DecodesUriProperly()
        {
            WebHostSettings      webHostSettings = new WebHostSettings();
            WebScriptHostManager manager         = new WebScriptHostManager(new ScriptHostConfiguration(), new SecretManager(), webHostSettings);

            // Initialize the
            FunctionMetadata metadata = new FunctionMetadata();

            metadata.Bindings.Add(new HttpTriggerBindingMetadata
            {
                Type = "HttpTrigger"
            });
            TestInvoker invoker = new TestInvoker();
            Collection <ParameterDescriptor> parameters = new Collection <ParameterDescriptor>();
            Collection <FunctionDescriptor>  functions  = new Collection <FunctionDescriptor>()
            {
                new FunctionDescriptor("Foo Bar", invoker, metadata, parameters),
                new FunctionDescriptor("éà  中國", invoker, metadata, parameters)
            };

            manager.InitializeHttpFunctions(functions);

            Uri uri    = new Uri("http://local/api/Foo Bar");
            var result = manager.GetHttpFunctionOrNull(uri);

            Assert.Same(functions[0], result);

            uri    = new Uri("http://local/api/éà  中國");
            result = manager.GetHttpFunctionOrNull(uri);
            Assert.Same(functions[1], result);
        }
        public WebScriptHostManager(ScriptHostConfiguration config,
                                    ISecretManagerFactory secretManagerFactory,
                                    IScriptEventManager eventManager,
                                    ScriptSettingsManager settingsManager,
                                    WebHostSettings webHostSettings,
                                    IWebJobsRouter router,
                                    ILoggerFactory loggerFactory,
                                    IScriptHostFactory scriptHostFactory = null,
                                    ISecretsRepositoryFactory secretsRepositoryFactory = null,
                                    HostPerformanceManager hostPerformanceManager      = null,
                                    ILoggerProviderFactory loggerProviderFactory       = null,
                                    int hostTimeoutSeconds = 30,
                                    int hostPollingIntervalMilliseconds = 500)
            : base(config, settingsManager, scriptHostFactory, eventManager, environment: null,
                   hostPerformanceManager: hostPerformanceManager, loggerProviderFactory: loggerProviderFactory)
        {
            _config = config;

            _metricsLogger      = new WebHostMetricsLogger();
            _exceptionHandler   = new WebScriptHostExceptionHandler(this);
            _webHostSettings    = webHostSettings;
            _settingsManager    = settingsManager;
            _hostTimeoutSeconds = hostTimeoutSeconds;
            _hostRunningPollIntervalMilliseconds = hostPollingIntervalMilliseconds;
            _router = router;

            config.IsSelfHost = webHostSettings.IsSelfHost;

            secretsRepositoryFactory = secretsRepositoryFactory ?? new DefaultSecretsRepositoryFactory();
            var secretsRepository = secretsRepositoryFactory.Create(settingsManager, webHostSettings, config);

            _secretManager = secretManagerFactory.Create(settingsManager, loggerFactory.CreateLogger(ScriptConstants.LogCategoryHostGeneral), secretsRepository);

            _bindingWebHookProvider = new WebJobsSdkExtensionHookProvider(_secretManager);
        }
Example #7
0
        private static WebHostSettings GetDefaultSettings(ScriptSettingsManager settingsManager)
        {
            WebHostSettings settings = new WebHostSettings();

            string home    = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebsiteHomePath);
            bool   isLocal = string.IsNullOrEmpty(home);

            if (isLocal)
            {
                settings.ScriptPath  = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebJobsScriptRoot);
                settings.LogPath     = Path.Combine(Path.GetTempPath(), @"Functions");
                settings.SecretsPath = HttpContext.Current.Server.MapPath("~/App_Data/Secrets");
            }
            else
            {
                // we're running in Azure
                settings.ScriptPath  = Path.Combine(home, @"site\wwwroot");
                settings.LogPath     = Path.Combine(home, @"LogFiles\Application\Functions");
                settings.SecretsPath = Path.Combine(home, @"data\Functions\secrets");
            }

            if (string.IsNullOrEmpty(settings.ScriptPath))
            {
                throw new InvalidOperationException("Unable to determine function script root directory.");
            }

            return(settings);
        }
Example #8
0
        public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings, IScriptHostFactory scriptHostFactory = null, ISecretsRepositoryFactory secretsRepositoryFactory = null)
            : base(config, settingsManager, scriptHostFactory)
        {
            _config           = config;
            _metricsLogger    = new WebHostMetricsLogger();
            _exceptionHandler = new WebScriptHostExceptionHandler(this);
            _webHostSettings  = webHostSettings;

            var systemEventGenerator = config.HostConfig.GetService <IEventGenerator>() ?? new EventGenerator();
            var systemTraceWriter    = new SystemTraceWriter(systemEventGenerator, settingsManager, TraceLevel.Verbose);

            if (config.TraceWriter != null)
            {
                config.TraceWriter = new CompositeTraceWriter(new TraceWriter[] { config.TraceWriter, systemTraceWriter });
            }
            else
            {
                config.TraceWriter = systemTraceWriter;
            }

            config.IsSelfHost = webHostSettings.IsSelfHost;

            _performanceManager     = new HostPerformanceManager(settingsManager, config.TraceWriter);
            _swaggerDocumentManager = new SwaggerDocumentManager(config);

            var secretsRepository = secretsRepositoryFactory.Create(settingsManager, webHostSettings, config);

            _secretManager = secretManagerFactory.Create(settingsManager, config.TraceWriter, secretsRepository);
        }
        private static ScriptHostConfiguration CreateScriptHostConfiguration(WebHostSettings settings)
        {
            InitializeFileSystem(settings.ScriptPath);

            var scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath  = settings.ScriptPath,
                RootLogPath     = settings.LogPath,
                FileLoggingMode = FileLoggingMode.DebugOnly,
                TraceWriter     = settings.TraceWriter
            };

            // If running on Azure Web App, derive the host ID from the default subdomain
            string hostId = _settingsManager.AzureWebsiteDefaultSubdomain;

            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();
            }

            return(scriptHostConfig);
        }
Example #10
0
 public WebScriptHostManager(ScriptHostConfiguration config,
                             ISecretManagerFactory secretManagerFactory,
                             IScriptEventManager eventManager,
                             ScriptSettingsManager settingsManager,
                             WebHostSettings webHostSettings)
     : this(config, secretManagerFactory, eventManager, settingsManager, webHostSettings, new ScriptHostFactory())
 {
 }
Example #11
0
        public static IServiceProvider AddWebJobsScriptHost(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddWebJobsScriptHostRouting();
            services.AddMvc()
            .AddXmlDataContractSerializerFormatters();

            services.TryAddEnumerable(ServiceDescriptor.Singleton <IHostedService, WebJobsScriptHostService>());

            // TODO: This is a direct port from the current model.
            // Some of those services (or the way we register them) may need to change
            var builder = new ContainerBuilder();

            // ScriptSettingsManager should be replaced. We're setting this here as a temporary step until
            // broader configuaration changes are made:
            ScriptSettingsManager.Instance.SetConfigurationFactory(() => configuration);
            builder.RegisterInstance(ScriptSettingsManager.Instance);

            builder.RegisterType <DefaultSecretManagerFactory>().As <ISecretManagerFactory>().SingleInstance();
            builder.RegisterType <ScriptEventManager>().As <IScriptEventManager>().SingleInstance();
            builder.RegisterType <EventGenerator>().As <IEventGenerator>().SingleInstance();
            builder.Register(c => WebHostSettings.CreateDefault(c.Resolve <ScriptSettingsManager>()));

            // Pass a specially-constructed LoggerFactory to the WebHostResolver. This LoggerFactory is only used
            // when there is no host available.
            // Only use this LoggerFactory for this constructor; use the registered ILoggerFactory below everywhere else.
            builder.RegisterType <WebHostResolver>().SingleInstance()
            .WithParameter(new ResolvedParameter(
                               (pi, ctx) => pi.ParameterType == typeof(ILoggerFactory),
                               (pi, ctx) => CreateLoggerFactory(string.Empty, ctx.Resolve <ScriptSettingsManager>(), ctx.Resolve <IEventGenerator>(), ctx.Resolve <WebHostSettings>())));

            // Register the LoggerProviderFactory, which defines the ILoggerProviders for the host.
            builder.RegisterType <WebHostLoggerProviderFactory>().As <ILoggerProviderFactory>().SingleInstance();

            // Temporary - This should be replaced with a simple type registration.
            builder.Register <IExtensionsManager>(c =>
            {
                var hostInstance = c.Resolve <WebScriptHostManager>().Instance;
                return(new ExtensionsManager(hostInstance.ScriptConfig.RootScriptPath, hostInstance.Logger, hostInstance.ScriptConfig.NugetFallBackPath));
            });

            // The services below need to be scoped to a pseudo-tenant (warm/specialized environment)
            builder.Register <WebScriptHostManager>(c => c.Resolve <WebHostResolver>().GetWebScriptHostManager()).ExternallyOwned();
            builder.Register <ISecretManager>(c => c.Resolve <WebHostResolver>().GetSecretManager()).ExternallyOwned();
            builder.RegisterType <WebFunctionsManager>().As <IWebFunctionsManager>().SingleInstance();
            builder.RegisterType <VirtualFileSystem>();
            builder.RegisterType <VirtualFileSystemMiddleware>();

            // Populate the container builder with registered services.
            // Doing this here will cause any services registered in the service collection to
            // override the registrations above
            builder.Populate(services);

            builder.Register(ct => ct.Resolve <WebHostResolver>().GetLoggerFactory(ct.Resolve <WebHostSettings>())).As <ILoggerFactory>().ExternallyOwned();

            var applicationContainer = builder.Build();

            return(new AutofacServiceProvider(applicationContainer));
        }
Example #12
0
        public static void Register(HttpConfiguration config, ScriptSettingsManager settingsManager = null,
                                    WebHostSettings settings = null, Action <ContainerBuilder, WebHostSettings> dependencyCallback = null)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            settingsManager = settingsManager ?? ScriptSettingsManager.Instance;
            settings        = settings ?? WebHostSettings.CreateDefault(settingsManager);

            var builder = new ContainerBuilder();

            builder.RegisterApiControllers(typeof(FunctionsController).Assembly);
            AutofacBootstrap.Initialize(settingsManager, builder, settings);

            // Invoke registration callback
            dependencyCallback?.Invoke(builder, settings);

            var container = builder.Build();

            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
            config.Formatters.Add(new PlaintextMediaTypeFormatter());
            config.Services.Replace(typeof(IExceptionHandler), new ExceptionProcessingHandler(config));
            AddMessageHandlers(config);

            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "Home",
                routeTemplate: string.Empty,
                defaults: new { controller = "Home" });

            config.Routes.MapHttpRoute(
                name: "Functions",
                routeTemplate: "{*uri}",
                defaults: new { controller = "Functions" });

            // Initialize WebHook Receivers
            config.InitializeReceiveGenericJsonWebHooks();
            config.InitializeReceiveAzureAlertWebHooks();
            config.InitializeReceiveKuduWebHooks();
            config.InitializeReceivePusherWebHooks();
            config.InitializeReceiveStripeWebHooks();
            config.InitializeReceiveTrelloWebHooks();
            config.InitializeReceiveDynamicsCrmWebHooks();
            config.InitializeReceiveMailChimpWebHooks();
            config.InitializeReceiveSlackWebHooks();
            config.InitializeReceiveBitbucketWebHooks();
            config.InitializeReceiveDropboxWebHooks();
            config.InitializeReceiveWordPressWebHooks();
            config.InitializeReceiveGitHubWebHooks();
            config.InitializeReceiveSalesforceWebHooks();
        }
Example #13
0
 public WebScriptHostManager(ScriptHostConfiguration config,
                             ISecretManagerFactory secretManagerFactory,
                             IScriptEventManager eventManager,
                             ScriptSettingsManager settingsManager,
                             WebHostSettings webHostSettings,
                             IScriptHostFactory scriptHostFactory)
     : this(config, secretManagerFactory, eventManager, settingsManager, webHostSettings, scriptHostFactory, new DefaultSecretsRepositoryFactory())
 {
 }
Example #14
0
 public WebHostResolver(ScriptSettingsManager settingsManager, ISecretManagerFactory secretManagerFactory,
                        IScriptEventManager eventManager, WebHostSettings settings, IWebJobsRouter router, ILoggerFactoryBuilder loggerFactoryBuilder)
 {
     _settingsManager      = settingsManager;
     _secretManagerFactory = secretManagerFactory;
     _eventManager         = eventManager;
     _router = router;
     _loggerFactoryBuilder = loggerFactoryBuilder;
     _settings             = settings;
 }
 public WebScriptHostManager(ScriptHostConfiguration config,
                             ISecretManagerFactory secretManagerFactory,
                             IScriptEventManager eventManager,
                             ScriptSettingsManager settingsManager,
                             WebHostSettings webHostSettings,
                             IWebJobsRouter router,
                             ILoggerFactory loggerFactory)
     : this(config, secretManagerFactory, eventManager, settingsManager, webHostSettings, router, loggerFactory, new ScriptHostFactory())
 {
 }
 public WebScriptHostManager(ScriptHostConfiguration config,
                             ISecretManagerFactory secretManagerFactory,
                             IScriptEventManager eventManager,
                             ScriptSettingsManager settingsManager,
                             WebHostSettings webHostSettings,
                             IWebJobsRouter router,
                             IScriptHostFactory scriptHostFactory,
                             ILoggerFactoryBuilder loggerFactoryBuilder)
     : this(config, secretManagerFactory, eventManager, settingsManager, webHostSettings, router, scriptHostFactory, new DefaultSecretsRepositoryFactory(), loggerFactoryBuilder)
 {
 }
        public static void Initialize(HttpConfiguration config, ScriptSettingsManager settingsManager = null,
            WebHostSettings settings = null, Action<ContainerBuilder, WebHostSettings> dependencyCallback = null)
        {
            Register(config, settingsManager, settings, dependencyCallback);

            var scriptHostManager = config.DependencyResolver.GetService<WebScriptHostManager>();
            if (scriptHostManager != null && !scriptHostManager.Initialized)
            {
                scriptHostManager.Initialize();
            }
        }
        public static void Register(HttpConfiguration config, ScriptSettingsManager settingsManager = null,
            WebHostSettings settings = null, Action<ContainerBuilder, WebHostSettings> dependencyCallback = null)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            settingsManager = settingsManager ?? ScriptSettingsManager.Instance;
            settings = settings ?? GetDefaultSettings(settingsManager);

            var builder = new ContainerBuilder();
            builder.RegisterApiControllers(typeof(FunctionsController).Assembly);
            AutofacBootstrap.Initialize(settingsManager, builder, settings);

            // Invoke registration callback
            dependencyCallback?.Invoke(builder, settings);

            var container = builder.Build();
            config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
            config.Formatters.Add(new PlaintextMediaTypeFormatter());
            config.MessageHandlers.Add(new WebScriptHostHandler(config));

            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "Home",
                routeTemplate: string.Empty,
                defaults: new { controller = "Home" });

            config.Routes.MapHttpRoute(
                name: "Functions",
                routeTemplate: "{*uri}",
                defaults: new { controller = "Functions" });

            // Initialize WebHook Receivers
            config.InitializeReceiveGenericJsonWebHooks();
            config.InitializeReceiveAzureAlertWebHooks();
            config.InitializeReceiveKuduWebHooks();
            config.InitializeReceivePusherWebHooks();
            config.InitializeReceiveStripeWebHooks();
            config.InitializeReceiveTrelloWebHooks();
            config.InitializeReceiveDynamicsCrmWebHooks();
            config.InitializeReceiveMailChimpWebHooks();
            config.InitializeReceiveSlackWebHooks();
            config.InitializeReceiveBitbucketWebHooks();
            config.InitializeReceiveDropboxWebHooks();
            config.InitializeReceiveWordPressWebHooks();
            config.InitializeReceiveGitHubWebHooks();
            config.InitializeReceiveSalesforceWebHooks();
        }
Example #19
0
        private static void VerifyAndEnableShadowCopy(WebHostSettings webHostSettings)
        {
            if (!FeatureFlags.IsEnabled(ScriptConstants.FeatureFlagDisableShadowCopy))
            {
                string currentShadowCopyDirectories = AppDomain.CurrentDomain.SetupInformation.ShadowCopyDirectories;
                string shadowCopyPath = GetShadowCopyPath(currentShadowCopyDirectories, webHostSettings.ScriptPath);

#pragma warning disable CS0618
                AppDomain.CurrentDomain.SetShadowCopyPath(shadowCopyPath);
#pragma warning restore CS0618
            }
        }
Example #20
0
        public static void Initialize(HttpConfiguration config, ScriptSettingsManager settingsManager = null,
                                      WebHostSettings settings = null, Action <ContainerBuilder, WebHostSettings> dependencyCallback = null)
        {
            Register(config, settingsManager, settings, dependencyCallback);

            var scriptHostManager = config.DependencyResolver.GetService <WebScriptHostManager>();

            if (scriptHostManager != null && !scriptHostManager.Initialized)
            {
                scriptHostManager.Initialize();
            }
        }
Example #21
0
        // TODO: FACAVAL (WEBHOOKS)
        //public WebHookReceiverManager GetWebHookReceiverManager(WebHostSettings settings)
        //{
        //    if (_activeReceiverManager != null)
        //    {
        //        return _activeReceiverManager;
        //    }

        //    lock (_syncLock)
        //    {
        //        EnsureInitialized(settings);

        //        return _activeReceiverManager ?? _standbyReceiverManager;
        //    }
        //}

        internal void EnsureInitialized(WebHostSettings settings)
        {
            if (!WebScriptHostManager.InStandbyMode)
            {
                // standby mode can only change from true to false
                // when standby mode changes, we reset all instances
                if (_activeHostManager == null)
                {
                    _settingsManager.Reset();

                    _activeScriptHostConfig = CreateScriptHostConfiguration(settings);
                    _activeHostManager      = new WebScriptHostManager(_activeScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, settings, _router, _loggerFactoryBuilder);
                    //_activeReceiverManager = new WebHookReceiverManager(_activeHostManager.SecretManager);
                    InitializeFileSystem();

                    if (_standbyHostManager != null)
                    {
                        // we're starting the one and only one
                        // standby mode specialization
                        _activeScriptHostConfig.TraceWriter.Info(Resources.HostSpecializationTrace);

                        // After specialization, we need to ensure that custom timezone
                        // settings configured by the user (WEBSITE_TIME_ZONE) are honored.
                        // DateTime caches timezone information, so we need to clear the cache.
                        TimeZoneInfo.ClearCachedData();
                    }

                    if (_standbyHostManager != null)
                    {
                        _standbyHostManager.Stop();
                        _standbyHostManager.Dispose();
                    }
                    //_standbyReceiverManager?.Dispose();
                    _standbyScriptHostConfig = null;
                    _standbyHostManager      = null;
                    //_standbyReceiverManager = null;
                }
            }
            else
            {
                if (_standbyHostManager == null)
                {
                    var standbySettings = CreateStandbySettings(settings);
                    _standbyScriptHostConfig = CreateScriptHostConfiguration(standbySettings, true);
                    _standbyHostManager      = new WebScriptHostManager(_standbyScriptHostConfig, _secretManagerFactory, _eventManager, _settingsManager, standbySettings, _router, _loggerFactoryBuilder);
                    // _standbyReceiverManager = new WebHookReceiverManager(_standbyHostManager.SecretManager);

                    InitializeFileSystem();
                    StandbyManager.Initialize(_standbyScriptHostConfig);
                }
            }
        }
Example #22
0
        protected void Application_Start()
        {
            var settingsManager = ScriptSettingsManager.Instance;
            var webHostSettings = WebHostSettings.CreateDefault(settingsManager);

            VerifyAndEnableShadowCopy(webHostSettings);

            using (var metricsLogger = new WebHostMetricsLogger())
                using (metricsLogger.LatencyEvent(MetricEventNames.ApplicationStartLatency))
                {
                    GlobalConfiguration.Configure(c => WebApiConfig.Initialize(c, settingsManager, webHostSettings));
                }
        }
        internal static void Initialize(ContainerBuilder builder, WebHostSettings settings)
        {
            // register the resolver so that it is disposed when the container
            // is disposed
            var webHostResolver = new WebHostResolver();

            builder.RegisterInstance(webHostResolver);

            // these services are externally owned by the WebHostResolver, and will be disposed
            // when the resolver is disposed
            builder.Register <SecretManager>(ct => webHostResolver.GetSecretManager(settings)).ExternallyOwned();
            builder.Register <WebScriptHostManager>(ct => webHostResolver.GetWebScriptHostManager(settings)).ExternallyOwned();
            builder.Register <WebHookReceiverManager>(ct => webHostResolver.GetWebHookReceiverManager(settings)).ExternallyOwned();
        }
        public ScriptHostConfiguration GetScriptHostConfiguration(WebHostSettings settings)
        {
            if (_activeScriptHostConfig != null)
            {
                return _activeScriptHostConfig;
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return _activeScriptHostConfig ?? _standbyScriptHostConfig;
            }
        }
        public WebScriptHostManager GetWebScriptHostManager(WebHostSettings settings)
        {
            if (_activeHostManager != null)
            {
                return _activeHostManager;
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return _activeHostManager ?? _standbyHostManager;
            }
        }
        public WebHookReceiverManager GetWebHookReceiverManager(WebHostSettings settings)
        {
            if (_activeReceiverManager != null)
            {
                return _activeReceiverManager;
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return _activeReceiverManager ?? _standbyReceiverManager;
            }
        }
        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();
            }

            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);

            WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig, secretManager);

            builder.RegisterInstance <WebScriptHostManager>(scriptHostManager);

            WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager);

            builder.RegisterInstance <WebHookReceiverManager>(webHookReceiverManager);

            if (!settings.IsSelfHost)
            {
                HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct));
            }
            else
            {
                Task.Run(() => scriptHostManager.RunAndBlock());
            }
        }
        internal static void Initialize(ScriptSettingsManager settingsManager, ContainerBuilder builder, WebHostSettings settings)
        {
            builder.RegisterInstance(settingsManager);

            builder.RegisterType<WebHostResolver>().SingleInstance();

            // these services are externally owned by the WebHostResolver, and will be disposed
            // when the resolver is disposed
            builder.RegisterType<DefaultSecretManagerFactory>().As<ISecretManagerFactory>().SingleInstance();
            builder.Register<TraceWriter>(ct => ct.ResolveOptional<WebScriptHostManager>()?.Instance?.TraceWriter ?? NullTraceWriter.Instance).ExternallyOwned();
            builder.Register<ISecretManager>(ct => ct.Resolve<WebHostResolver>().GetSecretManager(settings)).ExternallyOwned();
            builder.Register<WebScriptHostManager>(ct => ct.Resolve<WebHostResolver>().GetWebScriptHostManager(settings)).ExternallyOwned();
            builder.Register<WebHookReceiverManager>(ct => ct.Resolve<WebHostResolver>().GetWebHookReceiverManager(settings)).ExternallyOwned();
        }
        protected override void RegisterDependencies(ContainerBuilder builder, WebHostSettings settings)
        {
            TestFunctionKeys = new Dictionary<string, string>
            {
                { "key1", "1234" },
                { "key2", "1234" }
            };

            SecretManagerMock = BuildSecretManager();

            builder.RegisterInstance<ISecretManager>(SecretManagerMock.Object);

            base.RegisterDependencies(builder, settings);
        }
        public ISecretManager GetSecretManager(WebHostSettings settings)
        {
            if (_activeSecretManager != null)
            {
                return(_activeSecretManager);
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return(_activeSecretManager ?? _standbySecretManager);
            }
        }
Example #31
0
        public WebHookReceiverManager GetWebHookReceiverManager(WebHostSettings settings)
        {
            if (_activeReceiverManager != null)
            {
                return(_activeReceiverManager);
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return(_activeReceiverManager ?? _standbyReceiverManager);
            }
        }
Example #32
0
        public ScriptHostConfiguration GetScriptHostConfiguration(WebHostSettings settings)
        {
            if (_activeScriptHostConfig != null)
            {
                return(_activeScriptHostConfig);
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return(_activeScriptHostConfig ?? _standbyScriptHostConfig);
            }
        }
Example #33
0
        public WebScriptHostManager GetWebScriptHostManager(WebHostSettings settings)
        {
            if (_activeHostManager != null)
            {
                return(_activeHostManager);
            }

            lock (_syncLock)
            {
                EnsureInitialized(settings);

                return(_activeHostManager ?? _standbyHostManager);
            }
        }
Example #34
0
        private static ScriptHostConfiguration CreateScriptHostConfiguration(WebHostSettings settings)
        {
            InitializeFileSystem(settings.ScriptPath);

            var scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath  = settings.ScriptPath,
                RootLogPath     = settings.LogPath,
                FileLoggingMode = FileLoggingMode.DebugOnly,
                TraceWriter     = settings.TraceWriter
            };

            return(scriptHostConfig);
        }
        public AdminControllerTests()
        {
            _settingsManager = ScriptSettingsManager.Instance;
            testFunctions = new Collection<FunctionDescriptor>();

            var config = new ScriptHostConfiguration();
            hostMock = new Mock<ScriptHost>(MockBehavior.Strict, new object[] { config });
            hostMock.Setup(p => p.Functions).Returns(testFunctions);

            WebHostSettings settings = new WebHostSettings();
            managerMock = new Mock<WebScriptHostManager>(MockBehavior.Strict, new object[] { config, new TestSecretManagerFactory(), _settingsManager, settings });
            managerMock.SetupGet(p => p.Instance).Returns(hostMock.Object);

            testController = new AdminController(managerMock.Object);
        }
        public ISecretsRepository Create(ScriptSettingsManager settingsManager, WebHostSettings webHostSettings, ScriptHostConfiguration config, ILogger logger)
        {
            string secretStorageType = settingsManager.GetSetting(EnvironmentSettingNames.AzureWebJobsSecretStorageType);
            string storageString     = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage);

            if (secretStorageType != null && secretStorageType.Equals("Blob", StringComparison.OrdinalIgnoreCase) && storageString != null)
            {
                string siteSlotName = settingsManager.AzureWebsiteUniqueSlotName ?? config.HostConfig.HostId;
                return(new BlobStorageSecretsMigrationRepository(Path.Combine(webHostSettings.SecretsPath, "Sentinels"), storageString, siteSlotName, logger));
            }
            else
            {
                return(new FileSystemSecretsRepository(webHostSettings.SecretsPath));
            }
        }
            public Fixture()
            {
                TestFunctionRoot = Path.Combine(TestHelpers.FunctionsTestDirectory, "Functions");
                TestLogsRoot     = Path.Combine(TestHelpers.FunctionsTestDirectory, "Logs");
                TestSecretsRoot  = Path.Combine(TestHelpers.FunctionsTestDirectory, "Secrets");

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

                SecretsPath = Path.Combine(TestSecretsRoot, Guid.NewGuid().ToString());
                Directory.CreateDirectory(SecretsPath);
                string logRoot = Path.Combine(TestLogsRoot, Guid.NewGuid().ToString(), @"Functions");

                Directory.CreateDirectory(logRoot);
                FunctionsLogDir = Path.Combine(logRoot, @"Function");
                Directory.CreateDirectory(FunctionsLogDir);

                // Add some secret files (both old and valid)
                File.Create(Path.Combine(SecretsPath, ScriptConstants.HostMetadataFileName));
                File.Create(Path.Combine(SecretsPath, "WebHookTrigger.json"));
                File.Create(Path.Combine(SecretsPath, "QueueTriggerToBlob.json"));
                File.Create(Path.Combine(SecretsPath, "Foo.json"));
                File.Create(Path.Combine(SecretsPath, "Bar.json"));
                File.Create(Path.Combine(SecretsPath, "Invalid.json"));

                // Add some old file directories
                CreateTestFunctionLogs(FunctionsLogDir, "Foo");
                CreateTestFunctionLogs(FunctionsLogDir, "Bar");
                CreateTestFunctionLogs(FunctionsLogDir, "Baz");
                CreateTestFunctionLogs(FunctionsLogDir, "Invalid");

                ScriptHostConfiguration config = new ScriptHostConfiguration
                {
                    RootScriptPath     = @"TestScripts\Node",
                    RootLogPath        = logRoot,
                    FileLoggingEnabled = true
                };

                SecretManager   secretManager   = new SecretManager(SecretsPath);
                WebHostSettings webHostSettings = new WebHostSettings();

                HostManager = new WebScriptHostManager(config, secretManager, webHostSettings);
                Task task = Task.Run(() => { HostManager.RunAndBlock(); });

                TestHelpers.Await(() =>
                {
                    return(HostManager.IsRunning);
                }).GetAwaiter().GetResult();
            }
        public WebHostResolver(ScriptSettingsManager settingsManager, ISecretManagerFactory secretManagerFactory,
                               IScriptEventManager eventManager, WebHostSettings settings, IWebJobsRouter router, ILoggerProviderFactory loggerProviderFactory,
                               ILoggerFactory loggerFactory)
        {
            _settingsManager      = settingsManager;
            _secretManagerFactory = secretManagerFactory;
            _eventManager         = eventManager;
            _router   = router;
            _settings = settings;

            // _loggerProviderFactory is used for creating the LoggerFactory for each ScriptHost
            _loggerProviderFactory = loggerProviderFactory;

            // _loggerFactory is used when there is no host available.
            _loggerFactory = loggerFactory;
        }
        internal static ScriptHostConfiguration CreateScriptHostConfiguration(WebHostSettings settings)
        {
            InitializeFileSystem(settings.ScriptPath);

            var scriptHostConfig = new ScriptHostConfiguration()
            {
                RootScriptPath  = settings.ScriptPath,
                RootLogPath     = settings.LogPath,
                FileLoggingMode = FileLoggingMode.DebugOnly,
                TraceWriter     = settings.TraceWriter,
                IsSelfHost      = settings.IsSelfHost
            };

            scriptHostConfig.HostConfig.HostId = Utility.GetDefaultHostId(_settingsManager, scriptHostConfig);

            return(scriptHostConfig);
        }
        public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings, IScriptHostFactory scriptHostFactory = null)
            : base(config, settingsManager, scriptHostFactory)
        {
            _config = config;
            _metricsLogger = new WebHostMetricsLogger();
            _exceptionHandler = new WebScriptHostExceptionHandler(this);
            _webHostSettings = webHostSettings;

            var systemEventGenerator = config.HostConfig.GetService<IEventGenerator>() ?? new EventGenerator();
            var systemTraceWriter = new SystemTraceWriter(systemEventGenerator, settingsManager, TraceLevel.Verbose);
            if (config.TraceWriter != null)
            {
                config.TraceWriter = new CompositeTraceWriter(new TraceWriter[] { config.TraceWriter, systemTraceWriter });
            }
            else
            {
                config.TraceWriter = systemTraceWriter;
            }

            _secretManager = secretManagerFactory.Create(settingsManager, config.TraceWriter, webHostSettings.SecretsPath);
        }
        public ControllerScenarioTestFixture()
        {
            _config = new HttpConfiguration();
            _settingsManager = ScriptSettingsManager.Instance;

            HostSettings = new WebHostSettings
            {
                IsSelfHost = true,
                ScriptPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\sample"),
                LogPath = Path.Combine(Path.GetTempPath(), @"Functions"),
                SecretsPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\src\WebJobs.Script.WebHost\App_Data\Secrets")
            };

            WebApiConfig.Register(_config, _settingsManager, HostSettings, RegisterDependencies);

            HttpServer = new HttpServer(_config);
            this.HttpClient = new HttpClient(HttpServer);
            this.HttpClient.BaseAddress = new Uri("https://localhost/");

            WaitForHost();
        }
        private void EnsureInitialized(WebHostSettings settings)
        {
            // standby mode can only change from true to false
            // When standby mode changes, we reset all instances
            var standbyMode = WebScriptHostManager.InStandbyMode;
            if (!standbyMode)
            {
                if (_activeHostManager == null)
                {
                    if (_standbyHostManager != null)
                    {
                        // reintialize app settings if we were in standby
                        ReinitializeAppSettings();
                    }

                    _activeScriptHostConfig = GetScriptHostConfiguration(settings.ScriptPath, settings.LogPath);

                    _activeHostManager = new WebScriptHostManager(_activeScriptHostConfig, _secretManagerFactory, _settingsManager, settings);
                    _activeReceiverManager = new WebHookReceiverManager(_activeHostManager.SecretManager);

                    _standbyHostManager?.Dispose();
                    _standbyReceiverManager?.Dispose();

                    _standbyScriptHostConfig = null;
                    _standbyHostManager = null;
                    _standbyReceiverManager = null;
                    _settingsManager.Reset();
                }
            }
            else
            {
                if (_standbyHostManager == null)
                {
                    _standbyScriptHostConfig = GetScriptHostConfiguration(settings.ScriptPath, settings.LogPath);

                    _standbyHostManager = new WebScriptHostManager(_standbyScriptHostConfig, _secretManagerFactory, _settingsManager, settings);
                    _standbyReceiverManager = new WebHookReceiverManager(_standbyHostManager.SecretManager);
                }
            }
        }
 public ISecretManager GetSecretManager(WebHostSettings settings)
 {
     return GetWebScriptHostManager(settings).SecretManager;
 }
 public WebScriptHostManager(ScriptHostConfiguration config, ISecretManagerFactory secretManagerFactory, ScriptSettingsManager settingsManager, WebHostSettings webHostSettings)
     : this(config, secretManagerFactory, settingsManager, webHostSettings, new ScriptHostFactory())
 {
 }
        public static void WarmUp(WebHostSettings settings)
        {
            var traceWriter = new FileTraceWriter(Path.Combine(settings.LogPath, "Host"), TraceLevel.Info);
            ScriptHost host = null;
            try
            {
                traceWriter.Info("Warm up started");

                string rootPath = settings.ScriptPath;
                if (Directory.Exists(rootPath))
                {
                    Directory.Delete(rootPath, true);
                }
                Directory.CreateDirectory(rootPath);

                string content = ReadResourceString("Functions.host.json");
                File.WriteAllText(Path.Combine(rootPath, "host.json"), content);

                // read in the C# function
                string functionPath = Path.Combine(rootPath, "Test-CSharp");
                Directory.CreateDirectory(functionPath);
                content = ReadResourceString("Functions.Test_CSharp.function.json");
                File.WriteAllText(Path.Combine(functionPath, "function.json"), content);
                content = ReadResourceString("Functions.Test_CSharp.run.csx");
                File.WriteAllText(Path.Combine(functionPath, "run.csx"), content);

                // read in the F# function
                functionPath = Path.Combine(rootPath, "Test-FSharp");
                Directory.CreateDirectory(functionPath);
                content = ReadResourceString("Functions.Test_FSharp.function.json");
                File.WriteAllText(Path.Combine(functionPath, "function.json"), content);
                content = ReadResourceString("Functions.Test_FSharp.run.fsx");
                File.WriteAllText(Path.Combine(functionPath, "run.fsx"), content);

                traceWriter.Info("Warm up functions deployed");

                ScriptHostConfiguration config = new ScriptHostConfiguration
                {
                    RootScriptPath = rootPath,
                    FileLoggingMode = FileLoggingMode.Never,
                    RootLogPath = settings.LogPath,
                    TraceWriter = traceWriter,
                    FileWatchingEnabled = false
                };
                config.HostConfig.StorageConnectionString = null;
                config.HostConfig.DashboardConnectionString = null;

                host = ScriptHost.Create(ScriptSettingsManager.Instance, config);
                traceWriter.Info(string.Format("Starting Host (Id={0})", host.ScriptConfig.HostConfig.HostId));

                host.Start();

                var arguments = new Dictionary<string, object>
                {
                    { "input", "{}" }
                };
                host.CallAsync("Test-CSharp", arguments).Wait();
                host.CallAsync("Test-FSharp", arguments).Wait();
                host.Stop();

                traceWriter.Info("Warm up succeeded");
            }
            catch (Exception ex)
            {
                traceWriter.Error(string.Format("Warm up failed: {0}", ex));
            }
            finally
            {
                host?.Dispose();
                traceWriter.Dispose();
            }
        }
        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");
            WebHostSettings webHostSettings = new WebHostSettings();
            var secretManager = new SecretManager(SettingsManager, secretsPath, 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();
                }
            }
        }
 protected virtual void RegisterDependencies(ContainerBuilder builder, WebHostSettings settings)
 {
 }