PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/Raven.Server/Program.cs

https://github.com/andrewdavey/ravendb
C# | 356 lines | 318 code | 32 blank | 6 comment | 36 complexity | 15ece5bddeae72b6c62c15b46ba6995f MD5 | raw file
  1. //-----------------------------------------------------------------------
  2. // <copyright file="Program.cs" company="Hibernating Rhinos LTD">
  3. // Copyright (c) Hibernating Rhinos LTD. All rights reserved.
  4. // </copyright>
  5. //-----------------------------------------------------------------------
  6. using System;
  7. using System.Configuration.Install;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Reflection;
  12. using System.Security.Principal;
  13. using System.ServiceProcess;
  14. using log4net;
  15. using log4net.Appender;
  16. using log4net.Config;
  17. using log4net.Filter;
  18. using log4net.Layout;
  19. using log4net.Repository.Hierarchy;
  20. using Raven.Database;
  21. using Raven.Database.Config;
  22. using Raven.Database.Extensions;
  23. using Raven.Database.Impl.Logging;
  24. using Raven.Database.Server;
  25. using Raven.Http;
  26. namespace Raven.Server
  27. {
  28. internal class Program
  29. {
  30. private static void Main(string[] args)
  31. {
  32. if (Environment.UserInteractive)
  33. {
  34. try
  35. {
  36. InteractiveRun(args);
  37. }
  38. catch (ReflectionTypeLoadException e)
  39. {
  40. Console.WriteLine(e);
  41. foreach (var loaderException in e.LoaderExceptions)
  42. {
  43. Console.WriteLine("- - - -");
  44. Console.WriteLine(loaderException);
  45. }
  46. Environment.Exit(-1);
  47. }
  48. catch (Exception e)
  49. {
  50. Console.WriteLine(e);
  51. Environment.Exit(-1);
  52. }
  53. }
  54. else
  55. {
  56. // no try catch here, we want the exception to be logged by Windows
  57. ServiceBase.Run(new RavenService());
  58. }
  59. }
  60. private static void InteractiveRun(string[] args)
  61. {
  62. switch (GetArgument(args))
  63. {
  64. case "install":
  65. AdminRequired(InstallAndStart, "/install");
  66. break;
  67. case "uninstall":
  68. AdminRequired(EnsureStoppedAndUninstall, "/uninstall");
  69. break;
  70. case "start":
  71. AdminRequired(StartService, "/start");
  72. break;
  73. case "restart":
  74. AdminRequired(RestartService, "/restart");
  75. break;
  76. case "stop":
  77. AdminRequired(StopService, "/stop");
  78. break;
  79. case "restore":
  80. if (args.Length != 3)
  81. {
  82. PrintUsage();
  83. break;
  84. }
  85. RunRestoreOperation(args[1], args[2]);
  86. break;
  87. case "debug":
  88. RunInDebugMode(anonymousUserAccessMode: null, ravenConfiguration: new RavenConfiguration());
  89. break;
  90. case "ram":
  91. RunInDebugMode(anonymousUserAccessMode: AnonymousUserAccessMode.All, ravenConfiguration: new RavenConfiguration
  92. {
  93. RunInMemory = true,
  94. });
  95. break;
  96. #if DEBUG
  97. case "test":
  98. var dataDirectory = new RavenConfiguration().DataDirectory;
  99. IOExtensions.DeleteDirectory(dataDirectory);
  100. RunInDebugMode(anonymousUserAccessMode: AnonymousUserAccessMode.All, ravenConfiguration: new RavenConfiguration());
  101. break;
  102. #endif
  103. default:
  104. PrintUsage();
  105. break;
  106. }
  107. }
  108. private static void RunRestoreOperation(string backupLocation, string databaseLocation)
  109. {
  110. try
  111. {
  112. var ravenConfiguration = new RavenConfiguration();
  113. if(File.Exists(Path.Combine(backupLocation, "Raven.ravendb")))
  114. {
  115. ravenConfiguration.DefaultStorageTypeName =
  116. "Raven.Storage.Managed.TransactionalStorage, Raven.Storage.Managed";
  117. }
  118. else if(Directory.Exists(Path.Combine(backupLocation, "new")))
  119. {
  120. ravenConfiguration.DefaultStorageTypeName = "Raven.Storage.Esent.TransactionalStorage, Raven.Storage.Esent";
  121. }
  122. DocumentDatabase.Restore(ravenConfiguration, backupLocation, databaseLocation);
  123. }
  124. catch (Exception e)
  125. {
  126. Console.WriteLine(e);
  127. }
  128. }
  129. private static void AdminRequired(Action actionThatMayRequiresAdminPrivileges, string cmdLine)
  130. {
  131. var principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
  132. if (principal.IsInRole(WindowsBuiltInRole.Administrator) == false)
  133. {
  134. if (RunAgainAsAdmin(cmdLine))
  135. return;
  136. }
  137. actionThatMayRequiresAdminPrivileges();
  138. }
  139. private static bool RunAgainAsAdmin(string cmdLine)
  140. {
  141. try
  142. {
  143. var process = Process.Start(new ProcessStartInfo
  144. {
  145. Arguments = cmdLine,
  146. FileName = Assembly.GetExecutingAssembly().Location,
  147. Verb = "runas",
  148. });
  149. if (process != null)
  150. process.WaitForExit();
  151. return true;
  152. }
  153. catch (Exception)
  154. {
  155. return false;
  156. }
  157. }
  158. private static string GetArgument(string[] args)
  159. {
  160. if (args.Length == 0)
  161. return "debug";
  162. if (args[0].StartsWith("/") == false)
  163. return "help";
  164. return args[0].Substring(1);
  165. }
  166. private static void RunInDebugMode(AnonymousUserAccessMode? anonymousUserAccessMode, RavenConfiguration ravenConfiguration)
  167. {
  168. ConfigureDebugLogging();
  169. NonAdminHttp.EnsureCanListenToWhenInNonAdminContext(ravenConfiguration.Port);
  170. if (anonymousUserAccessMode.HasValue)
  171. ravenConfiguration.AnonymousUserAccessMode = anonymousUserAccessMode.Value;
  172. while (RunServer(ravenConfiguration))
  173. {
  174. }
  175. }
  176. private static void ConfigureDebugLogging()
  177. {
  178. if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config")))
  179. return;// that overrides the default config
  180. var loggerRepository = LogManager.GetRepository(typeof(HttpServer).Assembly);
  181. var patternLayout = new PatternLayout(PatternLayout.DefaultConversionPattern);
  182. var consoleAppender = new ConsoleAppender
  183. {
  184. Layout = patternLayout,
  185. };
  186. consoleAppender.ActivateOptions();
  187. ((Logger)loggerRepository.GetLogger(typeof(HttpServer).FullName)).AddAppender(consoleAppender);
  188. var fileAppender = new RollingFileAppender
  189. {
  190. AppendToFile = false,
  191. File = "Raven.Server.log",
  192. Layout = patternLayout,
  193. MaxSizeRollBackups = 3,
  194. MaximumFileSize = "1024KB",
  195. StaticLogFileName = true,
  196. LockingModel = new FileAppender.MinimalLock()
  197. };
  198. fileAppender.ActivateOptions();
  199. var asyncBufferingAppender = new AsyncBufferingAppender();
  200. asyncBufferingAppender.AddAppender(fileAppender);
  201. ((Hierarchy) loggerRepository).Root.AddAppender(asyncBufferingAppender);
  202. loggerRepository.Configured = true;
  203. }
  204. private static bool RunServer(RavenConfiguration ravenConfiguration)
  205. {
  206. using (var server = new RavenDbServer(ravenConfiguration))
  207. {
  208. var path = Path.Combine(Environment.CurrentDirectory, "default.raven");
  209. if (File.Exists(path))
  210. {
  211. Console.WriteLine("Loading data from: {0}", path);
  212. Smuggler.Smuggler.ImportData(ravenConfiguration.ServerUrl, path);
  213. }
  214. Console.WriteLine("Raven is ready to process requests. Build {0}, Version {1}", DocumentDatabase.BuildVersion, DocumentDatabase.ProductVersion);
  215. Console.WriteLine("Data directory: {0}", ravenConfiguration.DataDirectory);
  216. Console.WriteLine("HostName: {0} Port: {1}, Storage: {2}", ravenConfiguration.HostName ?? "<any>",
  217. ravenConfiguration.Port,
  218. server.Database.TransactionalStorage.FriendlyName);
  219. Console.WriteLine("Server Url: {0}", ravenConfiguration.ServerUrl);
  220. Console.WriteLine("Press <enter> to stop or 'cls' and <enter> to clear the log");
  221. while (true)
  222. {
  223. var readLine = Console.ReadLine() ?? "";
  224. switch (readLine.ToLowerInvariant())
  225. {
  226. case "cls":
  227. Console.Clear();
  228. break;
  229. case "reset":
  230. Console.Clear();
  231. return true;
  232. default:
  233. return false;
  234. }
  235. }
  236. }
  237. }
  238. private static void PrintUsage()
  239. {
  240. Console.WriteLine(
  241. @"
  242. Raven DB
  243. Document Database for the .Net Platform
  244. ----------------------------------------
  245. Copyright (C) 2010 - Hibernating Rhinos
  246. ----------------------------------------
  247. Command line ptions:
  248. Raven.Server - with no args, starts Raven in local server mode
  249. Raven.Server /install - installs and starts the Raven service
  250. Raven.Server /uninstall - stops and uninstalls the Raven service
  251. Raven.Server /start - starts the previously installed Raven service
  252. Raven.Server /stop - stops the previously installed Raven service
  253. Raven.Server /restart - restarts the previously installed Raven service
  254. Raven.Server /restore [backup location] [new database location]
  255. - restore a previously backed up database to the new
  256. location
  257. Enjoy...
  258. ");
  259. }
  260. private static void EnsureStoppedAndUninstall()
  261. {
  262. if (ServiceIsInstalled() == false)
  263. {
  264. Console.WriteLine("Service is not installed");
  265. }
  266. else
  267. {
  268. var stopController = new ServiceController(ProjectInstaller.SERVICE_NAME);
  269. if (stopController.Status == ServiceControllerStatus.Running)
  270. stopController.Stop();
  271. ManagedInstallerClass.InstallHelper(new[] { "/u", Assembly.GetExecutingAssembly().Location });
  272. }
  273. }
  274. private static void StopService()
  275. {
  276. var stopController = new ServiceController(ProjectInstaller.SERVICE_NAME);
  277. if (stopController.Status == ServiceControllerStatus.Running)
  278. {
  279. stopController.Stop();
  280. stopController.WaitForStatus(ServiceControllerStatus.Stopped);
  281. }
  282. }
  283. private static void StartService()
  284. {
  285. var stopController = new ServiceController(ProjectInstaller.SERVICE_NAME);
  286. if (stopController.Status != ServiceControllerStatus.Running)
  287. {
  288. stopController.Start();
  289. stopController.WaitForStatus(ServiceControllerStatus.Running);
  290. }
  291. }
  292. private static void RestartService()
  293. {
  294. var stopController = new ServiceController(ProjectInstaller.SERVICE_NAME);
  295. if (stopController.Status == ServiceControllerStatus.Running)
  296. {
  297. stopController.Stop();
  298. stopController.WaitForStatus(ServiceControllerStatus.Stopped);
  299. }
  300. if (stopController.Status != ServiceControllerStatus.Running)
  301. {
  302. stopController.Start();
  303. stopController.WaitForStatus(ServiceControllerStatus.Running);
  304. }
  305. }
  306. private static void InstallAndStart()
  307. {
  308. if (ServiceIsInstalled())
  309. {
  310. Console.WriteLine("Service is already installed");
  311. }
  312. else
  313. {
  314. ManagedInstallerClass.InstallHelper(new[] { Assembly.GetExecutingAssembly().Location });
  315. var startController = new ServiceController(ProjectInstaller.SERVICE_NAME);
  316. startController.Start();
  317. }
  318. }
  319. private static bool ServiceIsInstalled()
  320. {
  321. return (ServiceController.GetServices().Count(s => s.ServiceName == ProjectInstaller.SERVICE_NAME) > 0);
  322. }
  323. }
  324. }