1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2024-12-16 11:37:58 +02:00

applicationmode cleanup.

This commit is contained in:
kayone 2013-11-25 22:53:36 -08:00
parent c219be8c8d
commit 1e6817220a
28 changed files with 187 additions and 144 deletions

View File

@ -18,7 +18,7 @@ namespace NzbDrone.App.Test
[TestFixture]
public class ContainerFixture : TestBase
{
StartupArguments args = new StartupArguments("first", "second");
StartupContext args = new StartupContext("first", "second");
[Test]
public void should_be_able_to_resolve_indexers()

View File

@ -68,7 +68,7 @@ public void Route_should_call_service_start_when_run_in_service_mode()
serviceProvider.Setup(c => c.ServiceExist(It.IsAny<string>())).Returns(true);
serviceProvider.Setup(c => c.GetStatus(It.IsAny<string>())).Returns(ServiceControllerStatus.StartPending);
Subject.Route();
Subject.Route(ApplicationModes.Service);
serviceProvider.Verify(c => c.Run(It.IsAny<ServiceBase>()), Times.Once());
}

View File

@ -23,7 +23,7 @@ public abstract class AutomationTest
public AutomationTest()
{
new StartupArguments();
new StartupContext();
LogManager.Configuration = new LoggingConfiguration();
var consoleTarget = new ConsoleTarget { Layout = "${level}: ${message} ${exception}" };

View File

@ -35,9 +35,9 @@ public void IsProduction_should_return_false_when_run_within_nunit()
[Test]
public void should_use_path_from_arg_if_provided()
{
var args = new StartupArguments("-data=\"c:\\users\\test\\\"");
var args = new StartupContext("-data=\"c:\\users\\test\\\"");
Mocker.SetConstant<IStartupArguments>(args);
Mocker.SetConstant<IStartupContext>(args);
Subject.AppDataFolder.Should().Be("c:\\users\\test\\");
}
}

View File

@ -11,7 +11,7 @@ public class StartupArgumentsFixture : TestBase
[Test]
public void empty_array_should_return_empty_flags()
{
var args = new StartupArguments(new string[0]);
var args = new StartupContext(new string[0]);
args.Flags.Should().BeEmpty();
}
@ -21,7 +21,7 @@ public void empty_array_should_return_empty_flags()
[TestCase(" /t ")]
public void should_parse_single_flag(string arg)
{
var args = new StartupArguments(new[] { arg });
var args = new StartupContext(new[] { arg });
args.Flags.Should().HaveCount(1);
args.Flags.Contains("t").Should().BeTrue();
}
@ -32,7 +32,7 @@ public void should_parse_single_flag(string arg)
[TestCase(" /key=\"value\"")]
public void should_parse_args_with_alues(string arg)
{
var args = new StartupArguments(new[] { arg });
var args = new StartupContext(new[] { arg });
args.Args.Should().HaveCount(1);
args.Args["key"].Should().Be("value");
}

View File

@ -15,7 +15,7 @@ public class ServiceFactoryFixture : TestBase<ServiceFactory>
[SetUp]
public void setup()
{
Mocker.SetConstant(MainAppContainerBuilder.BuildContainer(new StartupArguments()));
Mocker.SetConstant(MainAppContainerBuilder.BuildContainer(new StartupContext()));
}
[Test]

View File

@ -15,7 +15,7 @@ public abstract class ContainerBuilderBase
public IContainer Container { get; private set; }
protected ContainerBuilderBase(IStartupArguments args, params string[] assemblies)
protected ContainerBuilderBase(IStartupContext args, params string[] assemblies)
{

View File

@ -22,7 +22,7 @@ public class AppFolderInfo : IAppFolderInfo
private readonly Environment.SpecialFolder DATA_SPECIAL_FOLDER = Environment.SpecialFolder.CommonApplicationData;
public AppFolderInfo(IDiskProvider diskProvider, IStartupArguments startupArguments)
public AppFolderInfo(IDiskProvider diskProvider, IStartupContext startupContext)
{
_diskProvider = diskProvider;
@ -33,9 +33,9 @@ public AppFolderInfo(IDiskProvider diskProvider, IStartupArguments startupArgume
_logger = NzbDroneLogger.GetLogger(this);
if (startupArguments.Args.ContainsKey(StartupArguments.APPDATA))
if (startupContext.Args.ContainsKey(StartupContext.APPDATA))
{
AppDataFolder = startupArguments.Args[StartupArguments.APPDATA];
AppDataFolder = startupContext.Args[StartupContext.APPDATA];
}
else
{

View File

@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
using System.ServiceProcess;
using NLog;
namespace NzbDrone.Common.EnvironmentInfo
@ -11,15 +12,21 @@ public interface IRuntimeInfo
{
bool IsUserInteractive { get; }
bool IsAdmin { get; }
bool IsWindowsService { get; }
}
public class RuntimeInfo : IRuntimeInfo
{
private readonly Logger _logger;
public RuntimeInfo(Logger logger)
public RuntimeInfo(Logger logger, IServiceProvider serviceProvider)
{
_logger = logger;
IsWindowsService = !IsUserInteractive &&
OsInfo.IsWindows &&
serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) &&
serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending;
}
public bool IsUserInteractive
@ -30,6 +37,8 @@ public bool IsUserInteractive
static RuntimeInfo()
{
IsProduction = InternalIsProduction();
}
public bool IsAdmin
@ -49,6 +58,8 @@ public bool IsAdmin
}
}
public bool IsWindowsService { get; private set; }
private static readonly string ProcessName = Process.GetCurrentProcess().ProcessName.ToLower();
public static bool IsProduction { get; private set; }

View File

@ -2,7 +2,7 @@
namespace NzbDrone.Common.EnvironmentInfo
{
public interface IStartupArguments
public interface IStartupContext
{
HashSet<string> Flags { get; }
Dictionary<string, string> Args { get; }
@ -10,7 +10,7 @@ public interface IStartupArguments
bool UninstallService { get; }
}
public class StartupArguments : IStartupArguments
public class StartupContext : IStartupContext
{
public const string APPDATA = "data";
public const string NO_BROWSER = "nobrowser";
@ -18,7 +18,7 @@ public class StartupArguments : IStartupArguments
internal const string UNINSTALL_SERVICE = "u";
public const string HELP = "?";
public StartupArguments(params string[] args)
public StartupContext(params string[] args)
{
Flags = new HashSet<string>();
Args = new Dictionary<string, string>();
@ -58,5 +58,6 @@ public bool UninstallService
return Flags.Contains(UNINSTALL_SERVICE);
}
}
}
}

View File

@ -9,9 +9,9 @@ namespace NzbDrone.Common.Instrumentation
{
public static class LogTargets
{
public static void Register(IStartupArguments startupArguments, bool updateApp, bool inConsole)
public static void Register(IStartupContext startupContext, bool updateApp, bool inConsole)
{
var appFolderInfo = new AppFolderInfo(new DiskProvider(), startupArguments);
var appFolderInfo = new AppFolderInfo(new DiskProvider(), startupContext);
LogManager.Configuration = new LoggingConfiguration();
@ -24,7 +24,7 @@ public static void Register(IStartupArguments startupArguments, bool updateApp,
}
else
{
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null).IsUserInteractive))
if (inConsole && (OsInfo.IsLinux || new RuntimeInfo(null, new ServiceProvider()).IsUserInteractive))
{
RegisterConsole();
}

View File

@ -86,7 +86,7 @@
<Compile Include="EnsureThat\Param.cs" />
<Compile Include="EnsureThat\Resources\ExceptionMessages.Designer.cs" />
<Compile Include="EnvironmentInfo\BuildInfo.cs" />
<Compile Include="EnvironmentInfo\StartupArguments.cs" />
<Compile Include="EnvironmentInfo\StartupContext.cs" />
<Compile Include="EnvironmentInfo\RuntimeInfo.cs" />
<Compile Include="EnvironmentInfo\OsInfo.cs" />
<Compile Include="Exceptions\NzbDroneException.cs" />

View File

@ -1,7 +1,5 @@
using System;
using System.Threading;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Host;
@ -16,26 +14,9 @@ public static void Main(string[] args)
{
try
{
var startupArgs = new StartupArguments(args);
var startupArgs = new StartupContext(args);
LogTargets.Register(startupArgs, false, true);
var container = Bootstrap.Start(startupArgs, new ConsoleAlerts());
if (startupArgs.InstallService || startupArgs.UninstallService)
{
return;
}
var serviceFactory = container.Resolve<INzbDroneServiceFactory>();
while (!serviceFactory.IsServiceStopped)
{
Thread.Sleep(1000);
}
}
catch (TerminateApplicationException e)
{
Logger.Info("Application has been terminated. Reason " + e.Reason);
return;
Bootstrap.Start(startupArgs, new ConsoleAlerts());
}
catch (Exception e)
{

View File

@ -17,7 +17,7 @@ public class MediaCoverServiceFixture : CoreTest<MediaCoverService>
[SetUp]
public void Setup()
{
Mocker.SetConstant<IAppFolderInfo>(new AppFolderInfo(new DiskProvider(), Mocker.Resolve<IStartupArguments>()));
Mocker.SetConstant<IAppFolderInfo>(new AppFolderInfo(new DiskProvider(), Mocker.Resolve<IStartupContext>()));
}
[Test]

View File

@ -19,18 +19,18 @@ public class NzbDroneServiceFactory : ServiceBase, INzbDroneServiceFactory
private readonly IRuntimeInfo _runtimeInfo;
private readonly IHostController _hostController;
private readonly PriorityMonitor _priorityMonitor;
private readonly IStartupArguments _startupArguments;
private readonly IStartupContext _startupContext;
private readonly IBrowserService _browserService;
private readonly Logger _logger;
public NzbDroneServiceFactory(IConfigFileProvider configFileProvider, IHostController hostController,
IRuntimeInfo runtimeInfo, PriorityMonitor priorityMonitor, IStartupArguments startupArguments, IBrowserService browserService, Logger logger)
IRuntimeInfo runtimeInfo, PriorityMonitor priorityMonitor, IStartupContext startupContext, IBrowserService browserService, Logger logger)
{
_configFileProvider = configFileProvider;
_hostController = hostController;
_runtimeInfo = runtimeInfo;
_priorityMonitor = priorityMonitor;
_startupArguments = startupArguments;
_startupContext = startupContext;
_browserService = browserService;
_logger = logger;
}
@ -44,9 +44,8 @@ public void Start()
{
_hostController.StartServer();
if (!_startupArguments.Flags.Contains(StartupArguments.NO_BROWSER) &&
_runtimeInfo.IsUserInteractive &&
_configFileProvider.LaunchBrowser)
if (!_startupContext.Flags.Contains(StartupContext.NO_BROWSER)
&& _configFileProvider.LaunchBrowser)
{
_browserService.LaunchWebUI();
}

View File

@ -1,4 +1,7 @@
using System.Reflection;
using System;
using System.Reflection;
using System.Threading;
using NLog;
using NzbDrone.Common.Composition;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Instrumentation;
@ -7,18 +10,21 @@
namespace NzbDrone.Host
{
public class Bootstrap
public static class Bootstrap
{
public IContainer Container { get; private set; }
private static IContainer _container;
private static readonly Logger Logger = NzbDroneLogger.GetLogger();
public Bootstrap(StartupArguments args, IUserAlert userAlert)
public static void Start(StartupContext startupContext, IUserAlert userAlert, Action<IContainer> startCallback = null)
{
try
{
var logger = NzbDroneLogger.GetLogger();
GlobalExceptionHandlers.Register();
IgnoreCertErrorPolicy.Register();
logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
Logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
if (!PlatformValidation.IsValidate(userAlert))
@ -26,21 +32,101 @@ public Bootstrap(StartupArguments args, IUserAlert userAlert)
throw new TerminateApplicationException("Missing system requirements");
}
Container = MainAppContainerBuilder.BuildContainer(args);
_container = MainAppContainerBuilder.BuildContainer(startupContext);
var appMode = GetApplicationMode(startupContext);
}
Start(appMode);
public void Start()
if (startCallback != null)
{
DbFactory.RegisterDatabase(Container);
Container.Resolve<Router>().Route();
startCallback(_container);
}
public void EnsureSingleInstance()
SpinToExit(appMode);
}
catch (TerminateApplicationException e)
{
Container.Resolve<ISingleInstancePolicy>().EnforceSingleInstance();
Logger.Info("Application has been terminated. Reason " + e.Reason);
}
}
private static void Start(ApplicationModes applicationModes)
{
if (!IsInUtilityMode(applicationModes))
{
EnsureSingleInstance();
}
DbFactory.RegisterDatabase(_container);
_container.Resolve<Router>().Route(applicationModes);
}
private static void SpinToExit(ApplicationModes applicationModes)
{
if (IsInUtilityMode(applicationModes))
{
return;
}
var serviceFactory = _container.Resolve<INzbDroneServiceFactory>();
while (!serviceFactory.IsServiceStopped)
{
Thread.Sleep(1000);
}
}
private static void EnsureSingleInstance()
{
_container.Resolve<ISingleInstancePolicy>().EnforceSingleInstance();
}
private static ApplicationModes GetApplicationMode(StartupContext startupContext)
{
if (startupContext.Flags.Contains(StartupContext.HELP))
{
return ApplicationModes.Help;
}
if (!OsInfo.IsLinux && startupContext.InstallService)
{
return ApplicationModes.InstallService;
}
if (!OsInfo.IsLinux && startupContext.UninstallService)
{
return ApplicationModes.UninstallService;
}
if (_container.Resolve<IRuntimeInfo>().IsWindowsService)
{
return ApplicationModes.Service;
}
return ApplicationModes.Interactive;
}
private static bool IsInUtilityMode(ApplicationModes applicationMode)
{
switch (applicationMode)
{
case ApplicationModes.InstallService:
case ApplicationModes.UninstallService:
case ApplicationModes.Help:
{
return true;
}
default:
{
return false;
}
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using NLog;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Processes;
using NzbDrone.Core.Configuration;
@ -14,12 +15,14 @@ public class BrowserService : IBrowserService
{
private readonly IProcessProvider _processProvider;
private readonly IConfigFileProvider _configFileProvider;
private readonly IRuntimeInfo _runtimeInfo;
private readonly Logger _logger;
public BrowserService(IProcessProvider processProvider, IConfigFileProvider configFileProvider, Logger logger)
public BrowserService(IProcessProvider processProvider, IConfigFileProvider configFileProvider, IRuntimeInfo runtimeInfo, Logger logger)
{
_processProvider = processProvider;
_configFileProvider = configFileProvider;
_runtimeInfo = runtimeInfo;
_logger = logger;
}
@ -27,13 +30,20 @@ public void LaunchWebUI()
{
var url = string.Format("http://localhost:{0}", _configFileProvider.Port);
try
{
if (_runtimeInfo.IsUserInteractive)
{
_logger.Info("Starting default browser. {0}", url);
_processProvider.OpenDefaultBrowser(url);
}
else
{
_logger.Debug("none-interactive runtime. Won't attempt to open browser.");
}
}
catch (Exception e)
{
_logger.ErrorException("Couldn't open defult browser to " + url, e);
_logger.ErrorException("Couldn't open default browser to " + url, e);
}
}
}

View File

@ -10,12 +10,12 @@ namespace NzbDrone.Host
{
public class MainAppContainerBuilder : ContainerBuilderBase
{
public static IContainer BuildContainer(StartupArguments args)
public static IContainer BuildContainer(StartupContext args)
{
return new MainAppContainerBuilder(args).Container;
}
private MainAppContainerBuilder(StartupArguments args)
private MainAppContainerBuilder(StartupContext args)
: base(args, "NzbDrone.Host", "NzbDrone.Common", "NzbDrone.Core", "NzbDrone.Api", "NzbDrone.SignalR")
{

View File

@ -1,7 +1,5 @@
using System.ServiceProcess;
using NLog;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.EnvironmentInfo;
namespace NzbDrone.Host
{
@ -9,28 +7,18 @@ public class Router
{
private readonly INzbDroneServiceFactory _nzbDroneServiceFactory;
private readonly IServiceProvider _serviceProvider;
private readonly IStartupArguments _startupArguments;
private readonly IConsoleService _consoleService;
private readonly IRuntimeInfo _runtimeInfo;
private readonly Logger _logger;
public Router(INzbDroneServiceFactory nzbDroneServiceFactory, IServiceProvider serviceProvider, IStartupArguments startupArguments,
IConsoleService consoleService, IRuntimeInfo runtimeInfo, Logger logger)
public Router(INzbDroneServiceFactory nzbDroneServiceFactory, IServiceProvider serviceProvider,
IConsoleService consoleService, Logger logger)
{
_nzbDroneServiceFactory = nzbDroneServiceFactory;
_serviceProvider = serviceProvider;
_startupArguments = startupArguments;
_consoleService = consoleService;
_runtimeInfo = runtimeInfo;
_logger = logger;
}
public void Route()
{
var appMode = GetApplicationMode();
Route(appMode);
}
public void Route(ApplicationModes applicationModes)
{
_logger.Info("Application mode: {0}", applicationModes);
@ -86,32 +74,6 @@ public void Route(ApplicationModes applicationModes)
}
}
private ApplicationModes GetApplicationMode()
{
if (!_runtimeInfo.IsUserInteractive &&
OsInfo.IsWindows &&
_serviceProvider.ServiceExist(ServiceProvider.NZBDRONE_SERVICE_NAME) &&
_serviceProvider.GetStatus(ServiceProvider.NZBDRONE_SERVICE_NAME) == ServiceControllerStatus.StartPending)
{
return ApplicationModes.Service;
}
if (_startupArguments.Flags.Contains(StartupArguments.HELP))
{
return ApplicationModes.Help;
}
if (!OsInfo.IsLinux && _startupArguments.InstallService)
{
return ApplicationModes.InstallService;
}
if (!OsInfo.IsLinux && _startupArguments.UninstallService)
{
return ApplicationModes.UninstallService;
}
return ApplicationModes.Interactive;
}
}
}

View File

@ -50,7 +50,7 @@ protected IEnumerable<SignalRMessage> SignalRMessages
public IntegrationTest()
{
new StartupArguments();
new StartupContext();
LogManager.Configuration = new LoggingConfiguration();
var consoleTarget = new ConsoleTarget { Layout = "${level}: ${message} ${exception}" };

View File

@ -12,7 +12,7 @@ public abstract class LoggingTest
protected static void InitLogging()
{
new StartupArguments();
new StartupContext();
TestLogger = LogManager.GetLogger("TestLogger");

View File

@ -93,7 +93,7 @@ public void TestBaseSetup()
Mocker.SetConstant(LogManager.GetLogger("TestLogger"));
Mocker.SetConstant<IStartupArguments>(new StartupArguments(new string[0]));
Mocker.SetConstant<IStartupContext>(new StartupContext(new string[0]));
LogManager.ReconfigExistingLoggers();

View File

@ -32,7 +32,7 @@ public void should_start_console_if_app_type_was_service_but_start_failed_becaus
Subject.Start(AppType.Service, targetFolder);
Mocker.GetMock<IProcessProvider>().Verify(c => c.SpawnNewProcess("c:\\NzbDrone\\NzbDrone.Console.exe", StartupArguments.NO_BROWSER), Times.Once());
Mocker.GetMock<IProcessProvider>().Verify(c => c.SpawnNewProcess("c:\\NzbDrone\\NzbDrone.Console.exe", StartupContext.NO_BROWSER), Times.Once());
ExceptionVerification.ExpectedWarns(1);
}

View File

@ -28,7 +28,7 @@ public static void Main(string[] args)
{
try
{
var startupArgument = new StartupArguments(args);
var startupArgument = new StartupContext(args);
LogTargets.Register(startupArgument, true, true);
Console.WriteLine("Starting NzbDrone Update Client");

View File

@ -5,15 +5,15 @@ namespace NzbDrone.Update
{
public class UpdateContainerBuilder : ContainerBuilderBase
{
private UpdateContainerBuilder(IStartupArguments startupArguments)
: base(startupArguments, "NzbDrone.Update", "NzbDrone.Common")
private UpdateContainerBuilder(IStartupContext startupContext)
: base(startupContext, "NzbDrone.Update", "NzbDrone.Common")
{
}
public static IContainer Build(IStartupArguments startupArguments)
public static IContainer Build(IStartupContext startupContext)
{
return new UpdateContainerBuilder(startupArguments).Container;
return new UpdateContainerBuilder(startupContext).Container;
}
}
}

View File

@ -73,7 +73,7 @@ private void Start(string installationFolder, string fileName)
_logger.Info("Starting {0}", fileName);
var path = Path.Combine(installationFolder, fileName);
_processProvider.SpawnNewProcess(path, StartupArguments.NO_BROWSER);
_processProvider.SpawnNewProcess(path, StartupContext.NO_BROWSER);
}
}
}

View File

@ -3,7 +3,6 @@
using System.Windows.Forms;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Host;
using NzbDrone.Host.Owin;
namespace NzbDrone.SysTray
{

View File

@ -16,22 +16,16 @@ public static void Main(string[] args)
{
try
{
var startupArgs = new StartupArguments(args);
var startupArgs = new StartupContext(args);
LogTargets.Register(startupArgs, false, true);
var bootstrap = new Bootstrap(startupArgs, new MessageBoxUserAlert());
bootstrap.EnsureSingleInstance();
bootstrap.Start();
bootstrap.Container.Register<ISystemTrayApp, SystemTrayApp>();
bootstrap.Container.Resolve<ISystemTrayApp>().Start();
}
catch (TerminateApplicationException e)
Bootstrap.Start(startupArgs, new MessageBoxUserAlert(), container =>
{
Logger.Info("Application has been terminated. Reason " + e.Reason);
container.Register<ISystemTrayApp, SystemTrayApp>();
var trayApp = container.Resolve<ISystemTrayApp>();
trayApp.Start();
});
}
catch (Exception e)
{