private static void RegisterServices(IKernel kernel)
        {
            var serverConfiguration = new ServerConfiguration();

            // Make sure %HOME% is correctly set
            EnsureHomeEnvironmentVariable();

            EnsureSiteBitnessEnvironmentVariable();

            IEnvironment environment = GetEnvironment();

            EnsureDotNetCoreEnvironmentVariable(environment);

            // Add various folders that never change to the process path. All child processes will inherit
            PrependFoldersToPath(environment);

            // Per request environment
            kernel.Bind <IEnvironment>().ToMethod(context => GetEnvironment(context.Kernel.Get <IDeploymentSettingsManager>(), HttpContext.Current))
            .InRequestScope();

            // General
            kernel.Bind <IServerConfiguration>().ToConstant(serverConfiguration);

            kernel.Bind <IBuildPropertyProvider>().ToConstant(new BuildPropertyProvider());

            System.Func <ITracer> createTracerThunk = () => GetTracer(kernel);

            // First try to use the current request profiler if any, otherwise create a new one
            var traceFactory = new TracerFactory(() => TraceServices.CurrentRequestTracer ?? createTracerThunk());

            kernel.Bind <ITracer>().ToMethod(context => TraceServices.CurrentRequestTracer ?? NullTracer.Instance);
            kernel.Bind <ITraceFactory>().ToConstant(traceFactory);
            TraceServices.SetTraceFactory(createTracerThunk);

            // Setup the deployment lock
            string lockPath           = Path.Combine(environment.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);
            string statusLockPath     = Path.Combine(lockPath, Constants.StatusLockFile);
            string sshKeyLockPath     = Path.Combine(lockPath, Constants.SSHKeyLockFile);
            string hooksLockPath      = Path.Combine(lockPath, Constants.HooksLockFile);

            _deploymentLock = new DeploymentLockFile(deploymentLockPath, kernel.Get <ITraceFactory>());
            _deploymentLock.InitializeAsyncLocks();

            var statusLock = new LockFile(statusLockPath, kernel.Get <ITraceFactory>());
            var sshKeyLock = new LockFile(sshKeyLockPath, kernel.Get <ITraceFactory>());
            var hooksLock  = new LockFile(hooksLockPath, kernel.Get <ITraceFactory>());

            kernel.Bind <IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto <SSHKeyController>();
            kernel.Bind <IOperationLock>().ToConstant(statusLock).WhenInjectedInto <DeploymentStatusManager>();
            kernel.Bind <IOperationLock>().ToConstant(hooksLock).WhenInjectedInto <WebHooksManager>();
            kernel.Bind <IOperationLock>().ToConstant(_deploymentLock);

            var shutdownDetector = new ShutdownDetector();

            shutdownDetector.Initialize();

            IDeploymentSettingsManager noContextDeploymentsSettingsManager =
                new DeploymentSettingsManager(new XmlSettings.Settings(GetSettingsPath(environment)));

            TraceServices.TraceLevel = noContextDeploymentsSettingsManager.GetTraceLevel();

            var noContextTraceFactory = new TracerFactory(() => GetTracerWithoutContext(environment, noContextDeploymentsSettingsManager));
            var etwTraceFactory       = new TracerFactory(() => new ETWTracer(string.Empty, string.Empty));

            kernel.Bind <IAnalytics>().ToMethod(context => new Analytics(context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                         context.Kernel.Get <IServerConfiguration>(),
                                                                         noContextTraceFactory));

            // Trace unhandled (crash) exceptions.
            AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
            {
                var ex = args.ExceptionObject as Exception;
                if (ex != null)
                {
                    kernel.Get <IAnalytics>().UnexpectedException(ex);
                }
            };

            // Trace shutdown event
            // Cannot use shutdownDetector.Token.Register because of race condition
            // with NinjectServices.Stop via WebActivator.ApplicationShutdownMethodAttribute
            Shutdown += () => TraceShutdown(environment, noContextDeploymentsSettingsManager);

            // LogStream service
            // The hooks and log stream start endpoint are low traffic end-points. Re-using it to avoid creating another lock
            var logStreamManagerLock = hooksLock;

            kernel.Bind <LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath),
                                                                                      context.Kernel.Get <IEnvironment>(),
                                                                                      context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                      context.Kernel.Get <ITracer>(),
                                                                                      shutdownDetector,
                                                                                      logStreamManagerLock));

            kernel.Bind <InfoRefsController>().ToMethod(context => new InfoRefsController(t => context.Kernel.Get(t)))
            .InRequestScope();

            kernel.Bind <CustomGitRepositoryHandler>().ToMethod(context => new CustomGitRepositoryHandler(t => context.Kernel.Get(t)))
            .InRequestScope();

            // Deployment Service
            kernel.Bind <ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment)))
            .InRequestScope();
            kernel.Bind <IDeploymentSettingsManager>().To <DeploymentSettingsManager>()
            .InRequestScope();

            kernel.Bind <IDeploymentStatusManager>().To <DeploymentStatusManager>()
            .InRequestScope();

            kernel.Bind <ISiteBuilderFactory>().To <SiteBuilderFactory>()
            .InRequestScope();

            kernel.Bind <IWebHooksManager>().To <WebHooksManager>()
            .InRequestScope();

            ITriggeredJobsManager triggeredJobsManager = new TriggeredJobsManager(
                etwTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>(),
                kernel.Get <IWebHooksManager>());

            kernel.Bind <ITriggeredJobsManager>().ToConstant(triggeredJobsManager)
            .InTransientScope();

            TriggeredJobsScheduler triggeredJobsScheduler = new TriggeredJobsScheduler(
                triggeredJobsManager,
                etwTraceFactory,
                environment,
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>());

            kernel.Bind <TriggeredJobsScheduler>().ToConstant(triggeredJobsScheduler)
            .InTransientScope();

            IContinuousJobsManager continuousJobManager = new ContinuousJobsManager(
                etwTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>());

            OperationManager.SafeExecute(triggeredJobsManager.CleanupDeletedJobs);
            OperationManager.SafeExecute(continuousJobManager.CleanupDeletedJobs);

            kernel.Bind <IContinuousJobsManager>().ToConstant(continuousJobManager)
            .InTransientScope();

            kernel.Bind <ILogger>().ToMethod(context => GetLogger(environment, context.Kernel))
            .InRequestScope();

            kernel.Bind <IDeploymentManager>().To <DeploymentManager>()
            .InRequestScope();
            kernel.Bind <IFetchDeploymentManager>().To <FetchDeploymentManager>()
            .InRequestScope();
            kernel.Bind <ISSHKeyManager>().To <SSHKeyManager>()
            .InRequestScope();

            kernel.Bind <IRepositoryFactory>().ToMethod(context => _deploymentLock.RepositoryFactory = new RepositoryFactory(context.Kernel.Get <IEnvironment>(),
                                                                                                                             context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                                                             context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            kernel.Bind <IApplicationLogsReader>().To <ApplicationLogsReader>()
            .InSingletonScope();

            // Git server
            kernel.Bind <IDeploymentEnvironment>().To <DeploymentEnvrionment>();

            kernel.Bind <IGitServer>().ToMethod(context => new GitExeServer(context.Kernel.Get <IEnvironment>(),
                                                                            _deploymentLock,
                                                                            GetRequestTraceFile(context.Kernel),
                                                                            context.Kernel.Get <IRepositoryFactory>(),
                                                                            context.Kernel.Get <IDeploymentEnvironment>(),
                                                                            context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                            context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            // Git Servicehook parsers
            kernel.Bind <IServiceHookHandler>().To <GenericHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandlerV2>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <DropboxHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodePlexHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodebaseHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitlabHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubCompatHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <KilnHgHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <VSOHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <OneDriveHandler>().InRequestScope();

            // SiteExtensions
            kernel.Bind <ISiteExtensionManager>().To <SiteExtensionManager>().InRequestScope();

            // Functions
            kernel.Bind <IFunctionManager>().To <FunctionManager>().InRequestScope();

            // Command executor
            kernel.Bind <ICommandExecutor>().To <CommandExecutor>().InRequestScope();

            MigrateSite(environment, noContextDeploymentsSettingsManager);
            RemoveOldTracePath(environment);
            RemoveTempFileFromUserDrive(environment);

            // Temporary fix for https://github.com/npm/npm/issues/5905
            EnsureNpmGlobalDirectory();
            EnsureUserProfileDirectory();

            // Skip SSL Certificate Validate
            if (Kudu.Core.Environment.SkipSslValidation)
            {
                ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); };
            }

            // Make sure webpages:Enabled is true. Even though we set it in web.config, it could be overwritten by
            // an Azure AppSetting that's supposed to be for the site only but incidently affects Kudu as well.
            ConfigurationManager.AppSettings["webpages:Enabled"] = "true";

            // Kudu does not rely owin:appStartup.  This is to avoid Azure AppSetting if set.
            if (ConfigurationManager.AppSettings["owin:appStartup"] != null)
            {
                // Set the appSetting to null since we cannot use AppSettings.Remove(key) (ReadOnly exception!)
                ConfigurationManager.AppSettings["owin:appStartup"] = null;
            }

            RegisterRoutes(kernel, RouteTable.Routes);

            // Register the default hubs route: ~/signalr
            GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel);
            GlobalConfiguration.Configuration.Filters.Add(
                new TraceDeprecatedActionAttribute(
                    kernel.Get <IAnalytics>(),
                    kernel.Get <ITraceFactory>()));
            GlobalConfiguration.Configuration.Filters.Add(new EnsureRequestIdHandlerAttribute());
        }
Exemple #2
0
        private static void RegisterServices(IKernel kernel)
        {
            var serverConfiguration = new ServerConfiguration();

            // Make sure %HOME% is correctly set
            EnsureHomeEnvironmentVariable();

            EnsureSiteBitnessEnvironmentVariable();

            IEnvironment environment = GetEnvironment();

            // Per request environment
            kernel.Bind <IEnvironment>().ToMethod(context => GetEnvironment(context.Kernel.Get <IDeploymentSettingsManager>()))
            .InRequestScope();

            // General
            kernel.Bind <HttpContextBase>().ToMethod(context => new HttpContextWrapper(HttpContext.Current))
            .InRequestScope();
            kernel.Bind <IServerConfiguration>().ToConstant(serverConfiguration);

            kernel.Bind <IBuildPropertyProvider>().ToConstant(new BuildPropertyProvider());

            System.Func <ITracer> createTracerThunk = () => GetTracer(environment, kernel);
            System.Func <ILogger> createLoggerThunk = () => GetLogger(environment, kernel);

            // First try to use the current request profiler if any, otherwise create a new one
            var traceFactory = new TracerFactory(() => TraceServices.CurrentRequestTracer ?? createTracerThunk());

            kernel.Bind <ITracer>().ToMethod(context => TraceServices.CurrentRequestTracer ?? NullTracer.Instance);
            kernel.Bind <ITraceFactory>().ToConstant(traceFactory);
            TraceServices.SetTraceFactory(createTracerThunk, createLoggerThunk);

            // Setup the deployment lock
            string lockPath           = Path.Combine(environment.SiteRootPath, Constants.LockPath);
            string deploymentLockPath = Path.Combine(lockPath, Constants.DeploymentLockFile);
            string statusLockPath     = Path.Combine(lockPath, Constants.StatusLockFile);
            string sshKeyLockPath     = Path.Combine(lockPath, Constants.SSHKeyLockFile);
            string hooksLockPath      = Path.Combine(lockPath, Constants.HooksLockFile);

            _deploymentLock = new DeploymentLockFile(deploymentLockPath, kernel.Get <ITraceFactory>());
            _deploymentLock.InitializeAsyncLocks();

            var statusLock = new LockFile(statusLockPath, kernel.Get <ITraceFactory>());
            var sshKeyLock = new LockFile(sshKeyLockPath, kernel.Get <ITraceFactory>());
            var hooksLock  = new LockFile(hooksLockPath, kernel.Get <ITraceFactory>());

            kernel.Bind <IOperationLock>().ToConstant(sshKeyLock).WhenInjectedInto <SSHKeyController>();
            kernel.Bind <IOperationLock>().ToConstant(statusLock).WhenInjectedInto <DeploymentStatusManager>();
            kernel.Bind <IOperationLock>().ToConstant(hooksLock).WhenInjectedInto <WebHooksManager>();
            kernel.Bind <IOperationLock>().ToConstant(_deploymentLock);

            var shutdownDetector = new ShutdownDetector();

            shutdownDetector.Initialize();

            IDeploymentSettingsManager noContextDeploymentsSettingsManager =
                new DeploymentSettingsManager(new XmlSettings.Settings(GetSettingsPath(environment)));

            var noContextTraceFactory = new TracerFactory(() => GetTracerWithoutContext(environment, noContextDeploymentsSettingsManager));

            kernel.Bind <IAnalytics>().ToMethod(context => new Analytics(context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                         context.Kernel.Get <IServerConfiguration>(),
                                                                         noContextTraceFactory));

            // Trace unhandled (crash) exceptions.
            AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
            {
                var ex = args.ExceptionObject as Exception;
                if (ex != null)
                {
                    kernel.Get <IAnalytics>().UnexpectedException(ex);
                }
            };

            // Trace shutdown event
            // Cannot use shutdownDetector.Token.Register because of race condition
            // with NinjectServices.Stop via WebActivator.ApplicationShutdownMethodAttribute
            Shutdown += () => TraceShutdown(environment, noContextDeploymentsSettingsManager);

            // LogStream service
            // The hooks and log stream start endpoint are low traffic end-points. Re-using it to avoid creating another lock
            var logStreamManagerLock = hooksLock;

            kernel.Bind <LogStreamManager>().ToMethod(context => new LogStreamManager(Path.Combine(environment.RootPath, Constants.LogFilesPath),
                                                                                      context.Kernel.Get <IEnvironment>(),
                                                                                      context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                      context.Kernel.Get <ITracer>(),
                                                                                      shutdownDetector,
                                                                                      logStreamManagerLock));

            kernel.Bind <InfoRefsController>().ToMethod(context => new InfoRefsController(t => context.Kernel.Get(t)))
            .InRequestScope();

            kernel.Bind <CustomGitRepositoryHandler>().ToMethod(context => new CustomGitRepositoryHandler(t => context.Kernel.Get(t)))
            .InRequestScope();

            // Deployment Service
            kernel.Bind <ISettings>().ToMethod(context => new XmlSettings.Settings(GetSettingsPath(environment)))
            .InRequestScope();
            kernel.Bind <IDeploymentSettingsManager>().To <DeploymentSettingsManager>()
            .InRequestScope();

            kernel.Bind <IDeploymentStatusManager>().To <DeploymentStatusManager>()
            .InRequestScope();

            kernel.Bind <ISiteBuilderFactory>().To <SiteBuilderFactory>()
            .InRequestScope();

            kernel.Bind <IWebHooksManager>().To <WebHooksManager>()
            .InRequestScope();

            ITriggeredJobsManager triggeredJobsManager = new TriggeredJobsManager(
                noContextTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>(),
                kernel.Get <IWebHooksManager>());

            kernel.Bind <ITriggeredJobsManager>().ToConstant(triggeredJobsManager)
            .InTransientScope();

            IContinuousJobsManager continuousJobManager = new ContinuousJobsManager(
                noContextTraceFactory,
                kernel.Get <IEnvironment>(),
                kernel.Get <IDeploymentSettingsManager>(),
                kernel.Get <IAnalytics>());

            triggeredJobsManager.CleanupDeletedJobs();
            continuousJobManager.CleanupDeletedJobs();

            kernel.Bind <IContinuousJobsManager>().ToConstant(continuousJobManager)
            .InTransientScope();

            TriggeredJobsScheduler triggeredJobsScheduler = new TriggeredJobsScheduler(
                triggeredJobsManager,
                noContextTraceFactory,
                kernel.Get <IAnalytics>(),
                environment,
                kernel.Get <IDeploymentSettingsManager>());

            kernel.Bind <TriggeredJobsScheduler>().ToConstant(triggeredJobsScheduler)
            .InTransientScope();

            kernel.Bind <ILogger>().ToMethod(context => GetLogger(environment, context.Kernel))
            .InRequestScope();

            kernel.Bind <IDeploymentManager>().To <DeploymentManager>()
            .InRequestScope();
            kernel.Bind <IAutoSwapHandler>().To <AutoSwapHandler>()
            .InRequestScope();
            kernel.Bind <ISSHKeyManager>().To <SSHKeyManager>()
            .InRequestScope();

            kernel.Bind <IRepositoryFactory>().ToMethod(context => _deploymentLock.RepositoryFactory = new RepositoryFactory(context.Kernel.Get <IEnvironment>(),
                                                                                                                             context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                                                                             context.Kernel.Get <ITraceFactory>(),
                                                                                                                             context.Kernel.Get <HttpContextBase>()))
            .InRequestScope();

            kernel.Bind <IApplicationLogsReader>().To <ApplicationLogsReader>()
            .InSingletonScope();

            // Git server
            kernel.Bind <IDeploymentEnvironment>().To <DeploymentEnvrionment>();

            kernel.Bind <IGitServer>().ToMethod(context => new GitExeServer(context.Kernel.Get <IEnvironment>(),
                                                                            _deploymentLock,
                                                                            GetRequestTraceFile(context.Kernel),
                                                                            context.Kernel.Get <IRepositoryFactory>(),
                                                                            context.Kernel.Get <IDeploymentEnvironment>(),
                                                                            context.Kernel.Get <IDeploymentSettingsManager>(),
                                                                            context.Kernel.Get <ITraceFactory>()))
            .InRequestScope();

            // Git Servicehook parsers
            kernel.Bind <IServiceHookHandler>().To <GenericHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <BitbucketHandlerV2>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <DropboxHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodePlexHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <CodebaseHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitlabHqHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <GitHubCompatHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <KilnHgHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <VSOHandler>().InRequestScope();
            kernel.Bind <IServiceHookHandler>().To <OneDriveHandler>().InRequestScope();

            // SiteExtensions
            kernel.Bind <ISiteExtensionManager>().To <SiteExtensionManager>().InRequestScope();

            // Command executor
            kernel.Bind <ICommandExecutor>().ToMethod(context => GetCommandExecutor(environment, context))
            .InRequestScope();

            MigrateSite(environment, noContextDeploymentsSettingsManager);
            RemoveOldTracePath(environment);
            RemoveTempFileFromUserDrive(environment);

            // Temporary fix for https://github.com/npm/npm/issues/5905
            EnsureNpmGlobalDirectory();
            EnsureUserProfileDirectory();

            RegisterRoutes(kernel, RouteTable.Routes);

            // Register the default hubs route: ~/signalr
            GlobalHost.DependencyResolver = new SignalRNinjectDependencyResolver(kernel);
            GlobalConfiguration.Configuration.Filters.Add(
                new TraceDeprecatedActionAttribute(
                    kernel.Get <IAnalytics>(),
                    kernel.Get <ITraceFactory>()));
            GlobalConfiguration.Configuration.Filters.Add(new EnsureRequestIdHandlerAttribute());
        }