Пример #1
0
        public void Default_database_path_settings()
        {
            var config = new RavenConfiguration("foo", ResourceType.Database, _emptySettingFile);

            config.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");

            config.Initialize();

            Assert.Equal(new PathSetting("Databases/foo").FullPath, config.Core.DataDirectory.FullPath);
            Assert.Equal(new PathSetting("Databases/foo/Indexes").FullPath, config.Indexing.StoragePath.FullPath);

            Assert.Null(config.Indexing.TempPath);

            Assert.Null(config.Storage.TempPath);

            // actual configuration is created in the following manner

            config = RavenConfiguration.CreateFrom(new RavenConfiguration(null, ResourceType.Server, _emptySettingFile), "foo",
                                                   ResourceType.Database);

            config.Initialize();

            Assert.Equal(new PathSetting("Databases/foo").FullPath, config.Core.DataDirectory.FullPath);
            Assert.Equal(new PathSetting("Databases/foo/Indexes").FullPath, config.Indexing.StoragePath.FullPath);

            Assert.Null(config.Indexing.TempPath);

            Assert.Null(config.Storage.TempPath);
        }
Пример #2
0
        protected DocumentDatabase CreateDocumentDatabase([CallerMemberName] string caller = null, bool runInMemory = true, string dataDirectory = null, Action <RavenConfiguration> modifyConfiguration = null)
        {
            var name = caller != null ? $"{caller}_{Interlocked.Increment(ref _counter)}" : Guid.NewGuid().ToString("N");

            if (string.IsNullOrEmpty(dataDirectory))
            {
                dataDirectory = NewDataPath(name);
            }

            _pathsToDelete.Add(dataDirectory);

            var configuration = new RavenConfiguration();

            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.MinNumberOfMapAttemptsAfterWhichBatchWillBeCanceledIfRunningLowOnMemory), int.MaxValue.ToString());
            configuration.Initialize();
            configuration.Core.ThrowIfAnyIndexOrTransformerCouldNotBeOpened = true;
            configuration.Core.RunInMemory   = runInMemory;
            configuration.Core.DataDirectory = dataDirectory;

            modifyConfiguration?.Invoke(configuration);

            var documentDatabase = new DocumentDatabase(name, configuration, null);

            documentDatabase.Initialize();

            return(documentDatabase);
        }
Пример #3
0
        public void Inherits_server_settings_and_appends_resource_specific_suffix_paths()
        {
            var server = new RavenConfiguration(null, ResourceType.Server);

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}Deployment");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.TempPath), $@"{_rootPathString}temp");
            server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.JournalsStoragePath), $@"{_rootPathString}Journals");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.StoragePath), $@"{_rootPathString}Indexes");
            server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.TempPath), $@"{_rootPathString}indexes-temp");
            server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.JournalsStoragePath), $@"{_rootPathString}Indexes-Journals");

            server.Initialize();

            var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database);

            database.Initialize();

            Assert.Equal(new PathSetting($@"{_rootPathString}Deployment\Databases\Foo").FullPath, database.Core.DataDirectory.FullPath);

            Assert.Equal(new PathSetting($@"{_rootPathString}temp\Databases\Foo").FullPath, database.Storage.TempPath.FullPath);
            Assert.Equal(new PathSetting($@"{_rootPathString}Journals\Databases\Foo").FullPath, database.Storage.JournalsStoragePath.FullPath);

            Assert.Equal(new PathSetting($@"{_rootPathString}Indexes\Databases\Foo").FullPath, database.Indexing.StoragePath.FullPath);
            Assert.Equal(new PathSetting($@"{_rootPathString}indexes-temp\Databases\Foo").FullPath, database.Indexing.TempPath.FullPath);
            Assert.Equal(new PathSetting($@"{_rootPathString}Indexes-Journals\Databases\Foo").FullPath, database.Indexing.JournalsStoragePath.FullPath);
        }
Пример #4
0
        public void Resource_specific_paths_do_not_require_any_suffixes()
        {
            var server = new RavenConfiguration(null, ResourceType.Server);

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}Deployment");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.TempPath), $@"{_rootPathString}temp");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.TempPath), $@"{_rootPathString}indexes-temp");

            server.Initialize();

            var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database);

            database.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}MyDatabase");

            database.SetSetting(RavenConfiguration.GetKey(x => x.Storage.TempPath), $@"{_rootPathString}my-temp-path");

            database.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.TempPath), $@"{_rootPathString}my-indexes-temp");

            database.Initialize();

            Assert.Equal(new PathSetting($@"{_rootPathString}MyDatabase").FullPath, database.Core.DataDirectory.FullPath);

            Assert.Equal(new PathSetting($@"{_rootPathString}my-temp-path").FullPath, database.Storage.TempPath.FullPath);

            Assert.Equal(new PathSetting($@"{_rootPathString}my-indexes-temp").FullPath, database.Indexing.TempPath.FullPath);
        }
Пример #5
0
        private static RavenServer CreateServer(int port, int tcpPort)
        {
            var configuration = new RavenConfiguration();

            configuration.Initialize();
            configuration.DebugLog.LogMode  = LogMode.None;
            configuration.Core.ServerUrl    = $"http://localhost:{port}";
            configuration.Core.TcpServerUrl = $"tcp://localhost:{tcpPort}";
            configuration.Server.Name       = ServerName;
            configuration.Core.RunInMemory  = true;
            string postfix = port == 8080 ? "" : "_" + port;

            configuration.Core.DataDirectory = Path.Combine(configuration.Core.DataDirectory, $"Tests{postfix}");
            configuration.Server.MaxTimeForTaskToWaitForDatabaseToLoad = new TimeSetting(10, TimeUnit.Seconds);
            configuration.Storage.AllowOn32Bits = true;

            IOExtensions.DeleteDirectory(configuration.Core.DataDirectory);

            var server = new RavenServer(configuration);

            server.Initialize();

            // TODO: Make sure to properly handle this when this is resolved:
            // TODO: https://github.com/dotnet/corefx/issues/5205
            // TODO: AssemblyLoadContext.GetLoadContext(typeof(RavenTestBase).GetTypeInfo().Assembly).Unloading +=

            return(server);
        }
Пример #6
0
        public DocumentsCrud()
        {
            _configuration = new RavenConfiguration();
            _configuration.Initialize();

            _configuration.Core.RunInMemory   = true;
            _configuration.Core.DataDirectory = Path.GetTempPath() + @"\crud";

            _documentDatabase = new DocumentDatabase("foo", _configuration, null);
            _documentDatabase.Initialize();
        }
Пример #7
0
        public void Restart()
        {
            if (Logger.IsInfoEnabled)
            {
                Logger.Info($"Restarting RavenDB Windows Service: {ServiceName}.");
            }

            _ravenServer.Dispose();
            var configuration = new RavenConfiguration(null, ResourceType.Server, CommandLineSwitches.CustomConfigPath);

            if (_args != null)
            {
                configuration.AddCommandLine(_args);
            }

            configuration.Initialize();
            _ravenServer = new RavenServer(configuration);
            Start(_args, _serviceStoppedCallback);

            configuration.Initialize();
        }
Пример #8
0
        public void IfConfigurationKeyIsStringArrayThenItShouldSupportValuesWithSemicolonPropely()
        {
            var configuration = new RavenConfiguration("Foo", ResourceType.Server);

            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Core.ServerUrls), "http://123.123.123.123:10105;http://123.123.123.124:10105");
            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Core.PublicServerUrl), "http://public.url.com");
            configuration.Initialize();

            Assert.NotNull(configuration.Core.ServerUrls);
            Assert.Equal(2, configuration.Core.ServerUrls.Length);
            Assert.Contains("http://123.123.123.123:10105", configuration.Core.ServerUrls);
            Assert.Contains("http://123.123.123.124:10105", configuration.Core.ServerUrls);
        }
Пример #9
0
        public RavenConfiguration GetConfiguration(string serverUrl = null, string tcpServerUrl = null, string certPath = null)
        {
            var configuration = new RavenConfiguration(null, ResourceType.Server);

            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Core.ServerUrl), serverUrl);
            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Core.TcpServerUrl), tcpServerUrl);
            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Security.CertificatePath), certPath);

            configuration.Initialize();

            return(configuration);
        }
Пример #10
0
        protected RachisConsensus <CountingStateMachine> SetupServer(bool bootstrap = false, int port = 0, int electionTimeout = 300, [CallerMemberName] string caller = null)
        {
            var tcpListener = new TcpListener(IPAddress.Loopback, port);

            tcpListener.Start();
            var ch = (char)(66 + _count++);

            if (bootstrap)
            {
                ch = (char)65;
                _count--;
            }

            var url = "tcp://localhost:" + ((IPEndPoint)tcpListener.LocalEndpoint).Port + "/?" + caller + "#" + ch;

            var server = StorageEnvironmentOptions.CreateMemoryOnly();

            int seed          = PredictableSeeds ? _random.Next(int.MaxValue) : _count;
            var configuration = new RavenConfiguration(caller, ResourceType.Server);

            configuration.Initialize();
            configuration.Core.RunInMemory        = true;
            configuration.Core.PublicServerUrl    = new UriSetting($"http://localhost:{((IPEndPoint)tcpListener.LocalEndpoint).Port}");
            configuration.Cluster.ElectionTimeout = new TimeSetting(electionTimeout, TimeUnit.Milliseconds);
            var serverStore = new RavenServer(configuration).ServerStore;

            serverStore.Initialize();
            var rachis             = new RachisConsensus <CountingStateMachine>(serverStore, seed);
            var storageEnvironment = new StorageEnvironment(server);

            rachis.Initialize(storageEnvironment, configuration, configuration.Core.ServerUrls[0]);
            rachis.OnDispose += (sender, args) =>
            {
                serverStore.Dispose();
                storageEnvironment.Dispose();
            };
            if (bootstrap)
            {
                rachis.Bootstrap(url, "A");
            }

            rachis.Url = url;
            _listeners.Add(tcpListener);
            RachisConsensuses.Add(rachis);
            var task = AcceptConnection(tcpListener, rachis);

            return(rachis);
        }
Пример #11
0
        private void Restart()
        {
            var options = _documentDatabase.DocumentsStorage.Environment.Options;

            options.OwnsPagers = false;
            _documentDatabase.Dispose();
            options.OwnsPagers = true;

            _configuration = new RavenConfiguration();
            _configuration.Core.DataDirectory = Path.GetTempPath() + @"\crud";
            _configuration.Initialize();
            _configuration.Core.RunInMemory = true;

            _documentDatabase = new DocumentDatabase("test", _configuration, null);
            _documentDatabase.Initialize(options);
        }
Пример #12
0
        private static void Validate(string key)
        {
            Environment.SetEnvironmentVariable(key, LogMode.Information.ToString());

            try
            {
                var configuration = new RavenConfiguration("test", ResourceType.Server);

                configuration.Initialize();

                Assert.Equal(LogMode.Information, configuration.Logs.Mode);
            }
            finally
            {
                Environment.SetEnvironmentVariable(key, null);
            }
        }
Пример #13
0
        public void ShouldWork()
        {
            var server = new RavenConfiguration(null, ResourceType.Server);

            server.SetSetting(RavenConfiguration.GetKey(x => x.Storage.ForceUsing32BitsPager), "true");
            server.Initialize(); // should not throw

            Assert.True(server.Storage.ForceUsing32BitsPager);

            var database = RavenConfiguration.CreateFrom(server, "dbName", ResourceType.Database);

            database.SetSetting(RavenConfiguration.GetKey(x => x.Storage.ForceUsing32BitsPager), "true");

            var e = Assert.Throws <InvalidOperationException>(() => database.Initialize());

            Assert.Equal($"Configuration '{RavenConfiguration.GetKey(x => x.Storage.ForceUsing32BitsPager)}' can only be set at server level.", e.Message);
        }
Пример #14
0
        protected virtual RavenServer GetNewServer(IDictionary <string, string> customSettings = null, bool deletePrevious = true, bool runInMemory = true, string partialPath = null, string customConfigPath = null)
        {
            lock (_getNewServerSync)
            {
                var configuration = new RavenConfiguration(Guid.NewGuid().ToString(), ResourceType.Server, customConfigPath);

                if (customSettings != null)
                {
                    foreach (var setting in customSettings)
                    {
                        configuration.SetSetting(setting.Key, setting.Value);
                    }
                }

                configuration.Initialize();
                configuration.Logs.Mode = LogMode.None;
                if (customSettings == null || customSettings.ContainsKey(RavenConfiguration.GetKey(x => x.Core.ServerUrls)) == false)
                {
                    configuration.Core.ServerUrls = new[] { "http://127.0.0.1:0" };
                }
                configuration.Server.Name        = ServerName;
                configuration.Core.RunInMemory   = runInMemory;
                configuration.Core.DataDirectory =
                    configuration.Core.DataDirectory.Combine(partialPath ?? $"Tests{Interlocked.Increment(ref _serverCounter)}");
                configuration.Server.MaxTimeForTaskToWaitForDatabaseToLoad = new TimeSetting(60, TimeUnit.Seconds);
                configuration.Replication.ReplicationMinimalHeartbeat      = new TimeSetting(100, TimeUnit.Milliseconds);
                configuration.Replication.RetryReplicateAfter = new TimeSetting(3, TimeUnit.Seconds);
                configuration.Cluster.AddReplicaTimeout       = new TimeSetting(10, TimeUnit.Seconds);
                configuration.Licensing.EulaAccepted          = true;
                if (customSettings == null || customSettings.ContainsKey(RavenConfiguration.GetKey(x => x.Core.FeaturesAvailability)) == false)
                {
                    configuration.Core.FeaturesAvailability = FeaturesAvailability.Experimental;
                }

                if (deletePrevious)
                {
                    IOExtensions.DeleteDirectory(configuration.Core.DataDirectory.FullPath);
                }

                var server = new RavenServer(configuration);
                server.Initialize();

                return(server);
            }
        }
Пример #15
0
        public void Should_create_data_in_directory_specified_at_server_level()
        {
            var server = new RavenConfiguration(null, ResourceType.Server);

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), $@"{_rootPathString}RavenData");

            server.Initialize();

            var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database);

            database.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), @"Items");

            database.Initialize();

            Assert.Equal(new PathSetting($@"{_rootPathString}RavenData\Items").FullPath, database.Core.DataDirectory.FullPath);
        }
Пример #16
0
        public void Database_creation_using_relative_path_creates_directories_incorrectly()
        {
            var server = new RavenConfiguration(null, ResourceType.Server);

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");
            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), "RavenData");

            server.Initialize();

            var database = RavenConfiguration.CreateFrom(server, "foo", ResourceType.Database);

            database.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");
            database.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), @"MyWork\MyDatabaseFolder");

            database.Initialize();

            Assert.Equal(new PathSetting("RavenData/MyWork/MyDatabaseFolder").FullPath, database.Core.DataDirectory.FullPath);
            Assert.Equal(new PathSetting("RavenData/MyWork/MyDatabaseFolder/Indexes").FullPath, database.Indexing.StoragePath.FullPath);
        }
Пример #17
0
        public RavenConfiguration GetConfiguration(
            string certPath = null,
            UnsecuredAccessAddressRange unsecuredAccessAddressRange = UnsecuredAccessAddressRange.Local,
            string publicServerUrl = null,
            string serverUrl       = null)
        {
            var configuration = new RavenConfiguration(null, ResourceType.Server);

            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Core.ServerUrls), serverUrl);
            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Core.PublicServerUrl), publicServerUrl);
            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Security.CertificatePath), certPath);
            configuration.SetSetting(
                RavenConfiguration.GetKey(x => x.Security.UnsecuredAccessAllowed), Enum.GetName(typeof(UnsecuredAccessAddressRange), unsecuredAccessAddressRange));
            configuration.Initialize();

            return(configuration);
        }
Пример #18
0
        public void Should_handle_APPDRIVE_properly_if_specified()
        {
            var server = new RavenConfiguration(null, ResourceType.Server);

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.RunInMemory), "true");

            server.SetSetting(RavenConfiguration.GetKey(x => x.Core.DataDirectory), @"APPDRIVE:\RavenData");

            server.Initialize();

            var rootPath = Path.GetPathRoot(AppContext.BaseDirectory);

            Assert.Equal(new PathSetting($@"{rootPath}RavenData").FullPath, server.Core.DataDirectory.FullPath);

            var database = RavenConfiguration.CreateFrom(server, "Foo", ResourceType.Database);

            database.Initialize();

            Assert.Equal(new PathSetting($@"{rootPath}RavenData\Databases\Foo").FullPath, database.Core.DataDirectory.FullPath);
            Assert.Equal(new PathSetting($@"{rootPath}RavenData\Databases\Foo\Indexes").FullPath, database.Indexing.StoragePath.FullPath);
        }
Пример #19
0
        public void CanDefineMoreThanOneAdditionalStoragePath()
        {
            var configuration = new RavenConfiguration();

            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.IndexStoragePath), "C:\\temp\\0");
            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.AdditionalIndexStoragePaths), "C:\\temp\\1;C:\\temp\\2");
            configuration.Initialize();

            Assert.Equal("C:\\temp\\0", configuration.Indexing.IndexStoragePath);
            Assert.Equal(2, configuration.Indexing.AdditionalIndexStoragePaths.Length);
            Assert.Equal("C:\\temp\\1", configuration.Indexing.AdditionalIndexStoragePaths[0]);
            Assert.Equal("C:\\temp\\2", configuration.Indexing.AdditionalIndexStoragePaths[1]);

            configuration = new RavenConfiguration();
            configuration.DatabaseName = "DB";
            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.IndexStoragePath), "C:\\temp\\0");
            configuration.SetSetting(RavenConfiguration.GetKey(x => x.Indexing.AdditionalIndexStoragePaths), "C:\\temp\\1;C:\\temp\\2");
            configuration.Initialize();

            Assert.Equal("C:\\temp\\0\\DB", configuration.Indexing.IndexStoragePath);
            Assert.Equal(2, configuration.Indexing.AdditionalIndexStoragePaths.Length);
            Assert.Equal("C:\\temp\\1\\DB", configuration.Indexing.AdditionalIndexStoragePaths[0]);
            Assert.Equal("C:\\temp\\2\\DB", configuration.Indexing.AdditionalIndexStoragePaths[1]);
        }
Пример #20
0
        private static void InteractiveRun(string[] args)
        {
            string backupLocation     = null;
            string restoreLocation    = null;
            bool   defrag             = false;
            string theUser            = null;
            Action actionToTake       = null;
            bool   launchBrowser      = false;
            bool   noLog              = false;
            var    ravenConfiguration = new RavenConfiguration();

            OptionSet optionSet = null;

            optionSet = new OptionSet
            {
                { "set={==}", "The configuration {0:option} to set to the specified {1:value}", (key, value) =>
                  {
                      ravenConfiguration.Settings[key] = value;
                      ravenConfiguration.Initialize();
                  } },
                { "nolog", "Don't use the default log", s => noLog = true },
                { "config=", "The config {0:file} to use", ravenConfiguration.LoadFrom },
                { "install", "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart) },
                { "user="******"Which user will be used", user => theUser = user },
                { "setup-perf-counters", "Setup the performance counters and the related permissions", key => actionToTake = () => AdminRequired(() => SetupPerfCounters(theUser)) },
                { "allow-blank-password-use", "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0)) },
                { "deny-blank-password-use", "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1)) },
                { "service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name },
                { "uninstall", "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall) },
                { "start", "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService) },
                { "restart", "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService) },
                { "stop", "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService) },
                { "ram", "Run RavenDB in RAM only", key =>
                  {
                      ravenConfiguration.Settings["Raven/RunInMemory"] = "true";
                      ravenConfiguration.RunInMemory = true;
                      actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog);
                  } },
                { "debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog) },
                { "browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true },
                { "help", "Help about the command line interface", key =>
                  {
                      actionToTake = () => PrintUsage(optionSet);
                  } },
                { "config-help", "Help about configuration options", key =>
                  {
                      actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs());
                  } },
                { "restore",
                  "Restores a RavenDB database from backup",
                  key => actionToTake = () =>
                  {
                      if (backupLocation == null || restoreLocation == null)
                      {
                          throw new OptionException("when using restore, source and destination must be specified", "restore");
                      }
                      RunRestoreOperation(backupLocation, restoreLocation, defrag);
                  } },
                { "defrag",
                  "Applicable only during restore, execute defrag after the restore is completed", key =>
                  {
                      defrag = true;
                  } },
                { "dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value },
                { "src=|source=", "The {0:path} of the backup", value => backupLocation = value },
                { "encrypt-self-config", "Encrypt the RavenDB configuration file", file =>
                  {
                      actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                  } },
                { "encrypt-config=", "Encrypt the specified {0:configuration file}", file =>
                  {
                      actionToTake = () => ProtectConfiguration(file);
                  } },
                { "decrypt-self-config", "Decrypt the RavenDB configuration file", file =>
                  {
                      actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                  } },
                { "decrypt-config=", "Decrypt the specified {0:configuration file}", file =>
                  {
                      actionToTake = () => UnprotectConfiguration(file);
                  } },
                { "installSSL={==}", "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
                  {
                      actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
                  } },
                { "uninstallSSL={==}", "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
                  {
                      actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
                  } }
            };


            try
            {
                if (args.Length == 0)                 // we default to executing in debug mode
                {
                    args = new[] { "--debug" }
                }
                ;

                optionSet.Parse(args);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                PrintUsage(optionSet);
                return;
            }

            if (actionToTake == null)
            {
                actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog);
            }

            actionToTake();
        }
Пример #21
0
        public static int Main(string[] args)
        {
            SetCurrentDirectoryToServerPath();

            string[] configurationArgs;
            try
            {
                configurationArgs = CommandLineSwitches.Process(args);
            }
            catch (CommandParsingException commandParsingException)
            {
                Console.WriteLine(commandParsingException.Message);
                CommandLineSwitches.ShowHelp();
                return(1);
            }

            if (CommandLineSwitches.ShouldShowHelp)
            {
                CommandLineSwitches.ShowHelp();
                return(0);
            }

            if (CommandLineSwitches.PrintVersionAndExit)
            {
                Console.WriteLine(ServerVersion.FullVersion);
                return(0);
            }

            new WelcomeMessage(Console.Out).Print();

            var targetSettingsFile = new PathSetting(string.IsNullOrEmpty(CommandLineSwitches.CustomConfigPath)
                ? "settings.json"
                : CommandLineSwitches.CustomConfigPath);

            var destinationSettingsFile = new PathSetting("settings.default.json");

            if (File.Exists(targetSettingsFile.FullPath) == false &&
                File.Exists(destinationSettingsFile.FullPath)) //just in case
            {
                File.Copy(destinationSettingsFile.FullPath, targetSettingsFile.FullPath);
            }

            var configuration = new RavenConfiguration(null, ResourceType.Server, CommandLineSwitches.CustomConfigPath);

            if (configurationArgs != null)
            {
                configuration.AddCommandLine(configurationArgs);
            }

            configuration.Initialize();

            LoggingSource.Instance.SetupLogMode(configuration.Logs.Mode, configuration.Logs.Path.FullPath);
            if (Logger.IsInfoEnabled)
            {
                Logger.Info($"Logging to {configuration.Logs.Path} set to {configuration.Logs.Mode} level.");
            }

            if (Logger.IsOperationsEnabled)
            {
                Logger.Operations(RavenCli.GetInfoText());
            }

            if (WindowsServiceRunner.ShouldRunAsWindowsService())
            {
                try
                {
                    WindowsServiceRunner.Run(CommandLineSwitches.ServiceName, configuration, configurationArgs);
                }
                catch (Exception e)
                {
                    if (Logger.IsInfoEnabled)
                    {
                        Logger.Info("Error running Windows Service", e);
                    }

                    return(1);
                }

                return(0);
            }

            RestartServer = () =>
            {
                ResetServerMre.Set();
                ShutdownServerMre.Set();
            };

            var rerun = false;
            RavenConfiguration configBeforeRestart = configuration;

            do
            {
                if (rerun)
                {
                    Console.WriteLine("\nRestarting Server...");
                    rerun = false;

                    configuration = new RavenConfiguration(null, ResourceType.Server, CommandLineSwitches.CustomConfigPath);

                    if (configurationArgs != null)
                    {
                        var argsAfterRestart = PostSetupCliArgumentsUpdater.Process(
                            configurationArgs, configBeforeRestart, configuration);

                        configuration.AddCommandLine(argsAfterRestart);
                        configBeforeRestart = configuration;
                    }

                    configuration.Initialize();
                }

                try
                {
                    using (var server = new RavenServer(configuration))
                    {
                        try
                        {
                            try
                            {
                                server.OpenPipes();
                            }
                            catch (Exception e)
                            {
                                if (Logger.IsInfoEnabled)
                                {
                                    Logger.Info("Unable to OpenPipe. Admin Channel will not be available to the user", e);
                                }
                                Console.WriteLine("Warning: Admin Channel is not available:" + e);
                            }

                            server.Initialize();

                            if (CommandLineSwitches.PrintServerId)
                            {
                                Console.WriteLine($"Server ID is {server.ServerStore.GetServerId()}.");
                            }

                            new RuntimeSettings(Console.Out).Print();

                            if (CommandLineSwitches.LaunchBrowser)
                            {
                                BrowserHelper.OpenStudioInBrowser(server.ServerStore.GetNodeHttpServerUrl());
                            }

                            new ClusterMessage(Console.Out, server.ServerStore).Print();

                            var prevColor = Console.ForegroundColor;
                            Console.Write("Server available on: ");
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.WriteLine($"{server.ServerStore.GetNodeHttpServerUrl()}");
                            Console.ForegroundColor = prevColor;

                            var tcpServerStatus = server.GetTcpServerStatus();
                            prevColor = Console.ForegroundColor;
                            Console.Write("Tcp listening on ");
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.WriteLine($"{string.Join(", ", tcpServerStatus.Listeners.Select(l => l.LocalEndpoint))}");
                            Console.ForegroundColor = prevColor;

                            Console.WriteLine("Server started, listening to requests...");

                            prevColor = Console.ForegroundColor;
                            Console.ForegroundColor = ConsoleColor.DarkGray;
                            Console.WriteLine("TIP: type 'help' to list the available commands.");
                            Console.ForegroundColor = prevColor;

                            IsRunningNonInteractive = false;
                            rerun = CommandLineSwitches.NonInteractive ||
                                    configuration.Core.SetupMode == SetupMode.Initial
                                ? RunAsNonInteractive()
                                : RunInteractive(server);

                            Console.WriteLine("Starting shut down...");
                            if (Logger.IsInfoEnabled)
                            {
                                Logger.Info("Server is shutting down");
                            }
                        }
                        catch (Exception e)
                        {
                            if (Logger.IsOperationsEnabled)
                            {
                                Logger.Operations("Failed to initialize the server", e);
                            }
                            Console.WriteLine(e);

                            return(-1);
                        }
                    }

                    Console.WriteLine("Shutdown completed");
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error during shutdown");
                    Console.WriteLine(e);
                    return(-2);
                }
                finally
                {
                    if (Logger.IsOperationsEnabled)
                    {
                        Logger.OperationsAsync("Server has shut down").Wait(TimeSpan.FromSeconds(15));
                    }
                }
            } while (rerun);

            return(0);
        }
Пример #22
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <DatabaseRestoreRequest>();

            DatabaseDocument databaseDocument = null;

            var databaseDocumentPath = MaintenanceActions.FindDatabaseDocument(restoreRequest.BackupLocation);

            if (File.Exists(databaseDocumentPath))
            {
                var databaseDocumentText = File.ReadAllText(databaseDocumentPath);
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id))
                                                                ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                                                : "A database name must be supplied if the restore location does not contain a valid Database.Document file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            if (databaseName == Constants.SystemDatabase)
            {
                return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest));
            }

            var existingDatabase = Database.Documents.GetDocumentMetadata("Raven/Databases/" + databaseName, null);

            if (existingDatabase != null)
            {
                return(GetMessageWithString("Cannot do an online restore for an existing database, delete the database " + databaseName + " and restore again.", HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (databaseDocument != null)
            {
                foreach (var setting in databaseDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename)))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);
            restoreRequest.DatabaseLocation  = ravenConfiguration.DataDirectory;
            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            var task = Task.Factory.StartNew(() =>
            {
                MaintenanceActions.Restore(ravenConfiguration, restoreRequest,
                                           msg =>
                {
                    restoreStatus.Messages.Add(msg);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                });

                if (databaseDocument == null)
                {
                    return;
                }

                databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
                if (restoreRequest.IndexesLocation != null)
                {
                    databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                }
                if (restoreRequest.JournalsLocation != null)
                {
                    databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                }
                databaseDocument.Id = databaseName;
                DatabasesLandlord.Protect(databaseDocument);
                DatabasesLandlord.SystemDatabase.Documents.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument),
                                                               new RavenJObject(), null);

                restoreStatus.Messages.Add("The new database was created");
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                               RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
            }, TaskCreationOptions.LongRunning);

            long id;

            Database.Tasks.AddTask(task, new object(), new TaskActions.PendingTaskDescription
            {
                StartTime = SystemTime.UtcNow,
                TaskType  = TaskActions.PendingTaskType.RestoreDatabase,
                Payload   = "Restoring database " + databaseName + " from " + restoreRequest.BackupLocation
            }, out id);


            return(GetMessageWithObject(new
            {
                OperationId = id
            }));
        }
Пример #23
0
		private static void InteractiveRun(string[] args)
		{
			string backupLocation = null;
			string restoreLocation = null;
			bool defrag = false;
			string theUser = null;
			Action actionToTake = null;
			bool launchBrowser = false;
			bool noLog = false;
			var ravenConfiguration = new RavenConfiguration();

			OptionSet optionSet = null;
			optionSet = new OptionSet
			{
				{"set={==}", "The configuration {0:option} to set to the specified {1:value}" , (key, value) =>
				{
					ravenConfiguration.Settings[key] = value;
					ravenConfiguration.Initialize();
				}},
				{"nolog", "Don't use the default log", s => noLog=true},
				{"config=", "The config {0:file} to use", ravenConfiguration.LoadFrom},
				{"install", "Installs the RavenDB service", key => actionToTake= () => AdminRequired(InstallAndStart)},
				{"user="******"Which user will be used", user=> theUser = user},
				{"setup-perf-counters", "Setup the performance counters and the related permissions", key => actionToTake = ()=> AdminRequired(()=>SetupPerfCounters(theUser))},
				{"allow-blank-password-use", "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0))},
				{"deny-blank-password-use", "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () =>  AdminRequired(() => SetLimitBlankPasswordUseRegValue(1))},
				{"service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name},
				{"uninstall", "Uninstalls the RavenDB service", key => actionToTake= () => AdminRequired(EnsureStoppedAndUninstall)},
				{"start", "Starts the RavenDB service", key => actionToTake= () => AdminRequired(StartService)},
				{"restart", "Restarts the RavenDB service", key => actionToTake= () => AdminRequired(RestartService)},
				{"stop", "Stops the RavenDB service", key => actionToTake= () => AdminRequired(StopService)},
				{"ram", "Run RavenDB in RAM only", key =>
				{
					ravenConfiguration.Settings["Raven/RunInMemory"] = "true";
					ravenConfiguration.RunInMemory = true;
					actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog);		
				}},
				{"debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog)},
				{"browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true},
				{"help", "Help about the command line interface", key =>
				{
					actionToTake = () => PrintUsage(optionSet);
				}},
				{"config-help", "Help about configuration options", key=>
				{
					actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs());
				}},
				{"restore", 
					"Restores a RavenDB database from backup",
					key => actionToTake = () =>
					{
						if(backupLocation == null || restoreLocation == null)
						{
							throw new OptionException("when using restore, source and destination must be specified", "restore");
						}
						RunRestoreOperation(backupLocation, restoreLocation, defrag);
					}},
				{"defrag", 
					"Applicable only during restore, execute defrag after the restore is completed", key =>
					{
						defrag = true;
					}},
				{"dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value},
				{"src=|source=", "The {0:path} of the backup", value => backupLocation = value},
				{"encrypt-self-config", "Encrypt the RavenDB configuration file", file =>
						{
							actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
						}},
				{"encrypt-config=", "Encrypt the specified {0:configuration file}", file =>
						{
							actionToTake = () => ProtectConfiguration(file);
						}},
				{"decrypt-self-config", "Decrypt the RavenDB configuration file", file =>
						{
							actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
						}},
				{"decrypt-config=", "Decrypt the specified {0:configuration file}", file =>
						{
							actionToTake = () => UnprotectConfiguration(file);
						}},
				{"installSSL={==}", "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
						{
							actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
						}},
				{"uninstallSSL={==}", "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
						{
							actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
						}}
			};


			try
			{
				if (args.Length == 0) // we default to executing in debug mode 
					args = new[] { "--debug" };

				optionSet.Parse(args);
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				PrintUsage(optionSet);
				return;
			}

			if (actionToTake == null)
				actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog);

			actionToTake();

		}
Пример #24
0
        private static void InteractiveRun(string[] args)
        {
            string backupLocation     = null;
            string restoreLocation    = null;
            Action actionToTake       = null;
            bool   launchBrowser      = false;
            var    ravenConfiguration = new RavenConfiguration();

            OptionSet optionSet = null;

            optionSet = new OptionSet
            {
                { "set={==}", "The configuration {0:option} to set to the specified {1:value}", (key, value) =>
                  {
                      ravenConfiguration.Settings[key] = value;
                      ravenConfiguration.Initialize();
                  } },
                { "config=", "The config {0:file} to use", path => ravenConfiguration.LoadFrom(path) },
                { "install", "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart, key) },
                { "service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name },
                { "uninstall", "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall, key) },
                { "start", "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService, key) },
                { "restart", "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService, key) },
                { "stop", "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService, key) },
                { "ram", "Run RavenDB in RAM only", key =>
                  {
                      ravenConfiguration.Settings["Raven/RunInMemory"] = "true";
                      ravenConfiguration.RunInMemory = true;
                      actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.All, ravenConfiguration, launchBrowser);
                  } },
                { "debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser) },
                { "browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true },
                { "help", "Help about the command line interface", key =>
                  {
                      actionToTake = () => PrintUsage(optionSet);
                  } },
                { "config-help", "Help about configuration options", key =>
                  {
                      actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs());
                  } },
                { "restore",
                  "Restores a RavenDB database from backup",
                  key => actionToTake = () =>
                  {
                      if (backupLocation == null || restoreLocation == null)
                      {
                          throw new OptionException("when using restore, source and destination must be specified", "restore");
                      }
                      RunRestoreOperation(backupLocation, restoreLocation);
                  } },
                { "dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value },
                { "src=|source=", "The {0:path} of the backup", value => backupLocation = value },
                { "encrypt-self-config", "Encrypt the RavenDB configuration file", file =>
                  {
                      actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                  } },
                { "encrypt-config=", "Encrypt the specified {0:configuration file}", file =>
                  {
                      actionToTake = () => ProtectConfiguration(file);
                  } },
                { "decrypt-self-config", "Decrypt the RavenDB configuration file", file =>
                  {
                      actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                  } },
                { "decrypt-config=", "Decrypt the specified {0:configuration file}", file =>
                  {
                      actionToTake = () => UnprotectConfiguration(file);
                  } }
            };


            try
            {
                if (args.Length == 0)                 // we default to executing in debug mode
                {
                    args = new[] { "--debug" }
                }
                ;

                optionSet.Parse(args);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                PrintUsage(optionSet);
                return;
            }

            if (actionToTake == null)
            {
                actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser);
            }

            actionToTake();
        }
Пример #25
0
        private static void InteractiveRun(string[] args)
        {
            var ioTestRequest = new GenericPerformanceTestRequest();

            string backupLocation            = null;
            string restoreLocation           = null;
            string restoreDatabaseName       = null;
            string restoreFilesystemName     = null;
            bool   restoreDisableReplication = false;
            bool   defrag = false;
            var    requiresRestoreAction = new HashSet <string>();
            bool   isRestoreAction       = false;
            var    requiresIoTestAction  = new HashSet <string>();
            bool   isIoTestAction        = false;
            Action actionToTake          = null;
            bool   launchBrowser         = false;
            bool   noLog = false;
            var    ravenConfiguration  = new RavenConfiguration();
            bool   waitForRestore      = true;
            int?   restoreStartTimeout = 15;

            var optionSet = new OptionSet();

            optionSet.Add("set={==}", OptionCategory.None, "The configuration {0:option} to set to the specified {1:value}", (key, value) =>
            {
                ravenConfiguration.Settings[key] = value;
                ravenConfiguration.Initialize();
            });
            optionSet.Add("nolog", OptionCategory.General, "Don't use the default log", s => noLog = true);
            optionSet.Add("config=", OptionCategory.General, "The config {0:file} to use", ravenConfiguration.LoadFrom);
            optionSet.Add("install", OptionCategory.Service, "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart));
            optionSet.Add("allow-blank-password-use", OptionCategory.Other, "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0)));
            optionSet.Add("deny-blank-password-use", OptionCategory.Other, "Deny to log on by using a Windows account that has a blank password", key => actionToTake   = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1)));
            optionSet.Add("service-name=", OptionCategory.Service, "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name);
            optionSet.Add("uninstall", OptionCategory.Service, "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall));
            optionSet.Add("start", OptionCategory.Service, "Starts the RavenDB service", key => actionToTake         = () => AdminRequired(StartService));
            optionSet.Add("restart", OptionCategory.Service, "Restarts the RavenDB service", key => actionToTake     = () => AdminRequired(RestartService));
            optionSet.Add("stop", OptionCategory.Service, "Stops the RavenDB service", key => actionToTake           = () => AdminRequired(StopService));
            optionSet.Add("ram", OptionCategory.General, "Run RavenDB in RAM only", key =>
            {
                ravenConfiguration.Settings[Constants.RunInMemory] = "true";
                ravenConfiguration.RunInMemory = true;
                ravenConfiguration.Initialize();
                actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog);
            });
            optionSet.Add("debug", OptionCategory.General, "Run RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog));
            optionSet.Add("browser|launchbrowser", OptionCategory.General, "After the server starts, launches the browser", key => launchBrowser = true);
            optionSet.Add("help", OptionCategory.Help, "Help about the command line interface", key =>
            {
                actionToTake = () => PrintUsage(optionSet);
            });
            optionSet.Add("config-help", OptionCategory.Help, "Help about configuration databaseOptions", key =>
            {
                actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs());
            });
            optionSet.Add("restore", OptionCategory.RestoreDatabase, "[Obsolete] Use --restore-system-database or --restore-database", key =>
            {
                actionToTake = () =>
                {
                    throw new OptionException("This method is obsolete, use --restore-system-database or --restore-database", "restore");
                };
                isRestoreAction = true;
            });
            optionSet.Add("restore-system-database", OptionCategory.RestoreDatabase, "Restores a SYSTEM database from backup.", key =>
            {
                actionToTake = () =>
                {
                    if (backupLocation == null || restoreLocation == null)
                    {
                        throw new OptionException("When using --restore-system-database, --restore-source and --restore-destination must be specified", "restore-system-database");
                    }
                    RunSystemDatabaseRestoreOperation(backupLocation, restoreLocation, defrag);
                };
                isRestoreAction = true;
            });
            optionSet.Add("restore-database=", OptionCategory.RestoreDatabase, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url =>
            {
                actionToTake = () =>
                {
                    if (backupLocation == null)
                    {
                        throw new OptionException("When using --restore-database, --restore-source must be specified", "restore-database");
                    }

                    Uri uri;
                    if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false)
                    {
                        throw new OptionException("Specified destination server url is not valid", "restore-database");
                    }

                    RunRemoteDatabaseRestoreOperation(backupLocation, restoreLocation, restoreDatabaseName, defrag, restoreDisableReplication, uri, waitForRestore, restoreStartTimeout);
                    Environment.Exit(0);
                };
                isRestoreAction = true;
            });
            optionSet.Add("restore-filesystem=", OptionCategory.RestoreFileSystem, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url =>
            {
                actionToTake = () =>
                {
                    if (backupLocation == null)
                    {
                        throw new OptionException("When using --restore-filesystem, --restore-source must be specified", "restore-filesystem");
                    }

                    Uri uri;
                    if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false)
                    {
                        throw new OptionException("Specified destination server url is not valid", "restore-database");
                    }

                    RunRemoteFilesystemRestoreOperation(backupLocation, restoreLocation, restoreFilesystemName, defrag, uri, waitForRestore, restoreStartTimeout);
                    Environment.Exit(0);
                };
                isRestoreAction = true;
            });
            optionSet.Add("restore-disable-replication", OptionCategory.RestoreDatabase, "Disables replication destinations in newly restored database", value =>
            {
                restoreDisableReplication = true;
                requiresRestoreAction.Add("restore-disable-replication");
            });
            optionSet.Add("restore-no-wait", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Return immediately without waiting for a restore to complete", value =>
            {
                waitForRestore = false;
                requiresRestoreAction.Add("restore-no-wait");
            });
            optionSet.Add("restore-start-timeout=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The maximum {0:timeout} in seconds to wait for another restore to complete. Default: 15 seconds.", value =>
            {
                int timeout;
                if (int.TryParse(value, out timeout) == false)
                {
                    throw new OptionException("Specified restore start timeout is not valid", "restore-start-timeout");
                }
                restoreStartTimeout = timeout;
                requiresRestoreAction.Add("restore-start-timeout");
            });
            optionSet.Add("restore-defrag", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Applicable only during restore, execute defrag after the restore is completed", key =>
            {
                defrag = true;
                requiresRestoreAction.Add("restore-defrag");
            });
            optionSet.Add("restore-destination=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the new database. If not specified it will be located in default data directory", value =>
            {
                restoreLocation = value;
                requiresRestoreAction.Add("restore-destination");
            });
            optionSet.Add("restore-source=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the backup", value =>
            {
                backupLocation = value;
                requiresRestoreAction.Add("restore-source");
            });
            optionSet.Add("restore-database-name=", OptionCategory.RestoreDatabase, "The {0:name} of the new database. If not specified, it will be extracted from backup. Only applicable during REMOTE restore", value =>
            {
                restoreDatabaseName = value;
                requiresRestoreAction.Add("restore-database-name");
            });
            optionSet.Add("restore-filesystem-name", OptionCategory.RestoreFileSystem, "The {0:name} of the new filesystem. If not specified, it will be extracted from backup.", value =>
            {
                restoreFilesystemName = value;
                requiresRestoreAction.Add("restore-filesystem-name");
            });
            optionSet.Add("io-test=", OptionCategory.IOTest, "Performs disk io test using {0:dir} as temporary dir path", path =>
            {
                ioTestRequest.Path = path;
                actionToTake       = () => IoTest(ioTestRequest);
                isIoTestAction     = true;
            });
            optionSet.Add("io-test-file-size=", OptionCategory.IOTest, "The {0:size} of test file for io test in MB (default: 1024MB)", value =>
            {
                int fileSize;
                if (int.TryParse(value, out fileSize) == false)
                {
                    throw new OptionException("Specified test file size is not valid", "io-test-file-size");
                }
                ioTestRequest.FileSize = fileSize * 1024 * 1024;
                requiresIoTestAction.Add("io-test-file-size");
            });
            optionSet.Add("io-test-threads=", OptionCategory.IOTest, "The {0:number} of threads to use during test", value =>
            {
                int threads;
                if (int.TryParse(value, out threads) == false)
                {
                    throw new OptionException("Specified amount of threads is not valid", "io-test-threads");
                }
                ioTestRequest.ThreadCount = threads;
                requiresIoTestAction.Add("io-test-threads");
            });
            optionSet.Add("io-test-time=", OptionCategory.IOTest, "The {0:number} of seconds to run the test (default: 30)", value =>
            {
                int testTime;
                if (int.TryParse(value, out testTime) == false)
                {
                    throw new OptionException("Specified test time is not valid", "io-test-time");
                }
                ioTestRequest.TimeToRunInSeconds = testTime;
                requiresIoTestAction.Add("io-test-time");
            });
            optionSet.Add("io-test-seed=", OptionCategory.IOTest, "The {0:seed} for random generator", value =>
            {
                int seed;
                if (int.TryParse(value, out seed) == false)
                {
                    throw new OptionException("Specified random seed is not valid", "io-test-seed");
                }
                ioTestRequest.RandomSeed = seed;
                requiresIoTestAction.Add("io-test-seed");
            });
            optionSet.Add("io-test-mode=", OptionCategory.IOTest, "The operation {0:mode} (read,write,mix) (default: write)", value =>
            {
                OperationType opType;
                if (Enum.TryParse(value, true, out opType) == false)
                {
                    throw new OptionException("Specified test mode is not valid", "io-test-mode");
                }
                ioTestRequest.OperationType = opType;
                requiresIoTestAction.Add("io-test-mode");
            });
            optionSet.Add("io-test-chunk-size=", OptionCategory.IOTest, "The {0:value} for chunk size in KB (default: 4 KB)", value =>
            {
                int chunkSize;
                if (int.TryParse(value, out chunkSize) == false)
                {
                    throw new OptionException("Specified test chunk size is not valid", "io-test-chunk-size");
                }
                ioTestRequest.ChunkSize = chunkSize * 1024;
                requiresIoTestAction.Add("io-test-chunk-size");
            });
            optionSet.Add("io-test-sequential", OptionCategory.IOTest, "Perform sequential read/write (default: random)", value =>
            {
                ioTestRequest.Sequential = true;
                requiresIoTestAction.Add("io-test-sequential");
            });
            optionSet.Add("io-test-buffering-type", OptionCategory.IOTest, "Buffering type (None,Read, ReadAndWrite) (default: None)", value =>
            {
                BufferingType bufferingType;
                if (Enum.TryParse(value, true, out bufferingType) == false)
                {
                    throw new OptionException("Specified buffering type is not valid", "io-test-buffering-type");
                }
                ioTestRequest.BufferingType = bufferingType;
                requiresIoTestAction.Add("io-test-buffering-type");
            });
            optionSet.Add("encrypt-self-config", OptionCategory.Encryption, "Encrypt the RavenDB configuration file", file =>
            {
                actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            });
            optionSet.Add("encrypt-config=", OptionCategory.Encryption, "Encrypt the specified {0:configuration file}", file =>
            {
                actionToTake = () => ProtectConfiguration(file);
            });
            optionSet.Add("decrypt-self-config", OptionCategory.Encryption, "Decrypt the RavenDB configuration file", file =>
            {
                actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
            });
            optionSet.Add("decrypt-config=", OptionCategory.Encryption, "Decrypt the specified {0:configuration file}", file =>
            {
                actionToTake = () => UnprotectConfiguration(file);
            });
            optionSet.Add("installSSL={==}", OptionCategory.SSL, "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
            {
                actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
            });
            optionSet.Add("uninstallSSL={==}", OptionCategory.SSL, "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
            {
                actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
            });
            optionSet.Add("update-version=", OptionCategory.Update, "Updates the specified {0:databaseName} to newest version", dbName =>
            {
                actionToTake = () => UpdateVersion(dbName);
            });

            try
            {
                if (args.Length == 0)                 // we default to executing in debug mode
                {
                    args = new[] { "--debug" }
                }
                ;

                optionSet.Parse(args);
            }
            catch (Exception e)
            {
                ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message);
                PrintUsage(optionSet);
                ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message);
                Environment.Exit(-1);
                return;
            }

            if (!isRestoreAction && requiresRestoreAction.Any())
            {
                var joinedActions = string.Join(", ", requiresRestoreAction);
                throw new OptionException(string.Format("When using {0}, --restore-source must be specified", joinedActions), joinedActions);
            }

            if (!isIoTestAction && requiresIoTestAction.Any())
            {
                var joinedActions = string.Join(", ", requiresRestoreAction);
                throw new OptionException(string.Format("When using {0}, --io-test must be specified", joinedActions), joinedActions);
            }

            if (actionToTake == null)
            {
                actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog);
            }

            actionToTake();
        }
Пример #26
0
		private static void InteractiveRun(string[] args)
		{
			string backupLocation = null;
			string restoreLocation = null;
			string restoreDatabaseName = null;
		    string restoreFilesystemName = null;
			bool defrag = false;
            var requiresRestoreAction = new HashSet<string>();
		    bool isRestoreAction = false;
			Action actionToTake = null;
			bool launchBrowser = false;
			bool noLog = false;
			var ravenConfiguration = new RavenConfiguration();
		    bool waitForRestore = true;
		    int? restoreStartTimeout = 15;

			OptionSet optionSet = null;
			optionSet = new OptionSet
			{
				{"set={==}", "The configuration {0:option} to set to the specified {1:value}" , (key, value) =>
				{
					ravenConfiguration.Settings[key] = value;
					ravenConfiguration.Initialize();
				}},
				{"nolog", "Don't use the default log", s => noLog=true},
				{"config=", "The config {0:file} to use", ravenConfiguration.LoadFrom},
				{"install", "Installs the RavenDB service", key => actionToTake= () => AdminRequired(InstallAndStart)},
				{"allow-blank-password-use", "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0))},
				{"deny-blank-password-use", "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () =>  AdminRequired(() => SetLimitBlankPasswordUseRegValue(1))},
				{"service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name},
				{"uninstall", "Uninstalls the RavenDB service", key => actionToTake= () => AdminRequired(EnsureStoppedAndUninstall)},
				{"start", "Starts the RavenDB service", key => actionToTake= () => AdminRequired(StartService)},
				{"restart", "Restarts the RavenDB service", key => actionToTake= () => AdminRequired(RestartService)},
				{"stop", "Stops the RavenDB service", key => actionToTake= () => AdminRequired(StopService)},
				{"ram", "Run RavenDB in RAM only", key =>
				{
					ravenConfiguration.Settings["Raven/RunInMemory"] = "true";
					ravenConfiguration.RunInMemory = true;
					ravenConfiguration.Initialize();
					actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog);		
				}},
				{"debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog)},
				{"browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true},
				{"help", "Help about the command line interface", key =>
				{
					actionToTake = () => PrintUsage(optionSet);
				}},
				{"config-help", "Help about configuration options", key=>
				{
					actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs());
				}},
				{"restore", "[Obsolete] Use --restore-system-database or --restore-database",
					key =>
					{
					    actionToTake = () =>
					    {
					        throw new OptionException("This method is obsolete, use --restore-system-database or --restore-database", "restore");
					    };
					    isRestoreAction = true;
					}
				},
				{"restore-system-database", "Restores a SYSTEM database from backup.",
					key =>
					{
					    actionToTake = () =>
					    {
					        if (backupLocation == null || restoreLocation == null)
					        {
					            throw new OptionException("when using --restore-system-database, --restore-source and --restore-destination must be specified", "restore-system-database");
					        }
					        RunSystemDatabaseRestoreOperation(backupLocation, restoreLocation, defrag);
					    };
					    isRestoreAction = true;
					}
				},
				{"restore-database=", "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", 
					url =>
					{
					    actionToTake = () =>
					    {
					        if (backupLocation == null)
					        {
					            throw new OptionException("when using --restore-database, --restore-source must be specified", "restore-database");
					        }

					        Uri uri;
					        if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false)
					        {
					            throw new OptionException("specified destination server url is not valid", "restore-database");
					        }

					        RunRemoteDatabaseRestoreOperation(backupLocation, restoreLocation, restoreDatabaseName, defrag, uri, waitForRestore, restoreStartTimeout);
					        Environment.Exit(0);
					    };
					    isRestoreAction = true;
					}
				},
                {"restore-filesystem=", "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.",
                    url =>
                    {
                        actionToTake = () =>
                        {
                            if (backupLocation == null)
                            {
                                throw new OptionException("when using --restore-filesystem, --restore-source must be specified", "restore-filesystem");
                            }

                            Uri uri;
                            if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false)
                            {
                                throw new OptionException("specified destination server url is not valid", "restore-database");
                            }

                            RunRemoteFilesystemRestoreOperation(backupLocation, restoreLocation, restoreFilesystemName, defrag, uri, waitForRestore, restoreStartTimeout);
                            Environment.Exit(0);
                        };
                        isRestoreAction = true;
                    }
                },
				{
				    "restore-no-wait", "Return immediately without waiting for a restore to complete", value =>
				    {
				        waitForRestore = false;
				        requiresRestoreAction.Add("restore-no-wait");
				    }
				},
                { "restore-start-timeout=", "The maximum {0:timeout} in seconds to wait for another restore to complete. Default: 15 seconds.", value =>
                {
                    int timeout;
                    if (int.TryParse(value, out timeout) == false)
                    {
                        throw new OptionException("specified restore start timeout is not valid", "restore-start-timeout");
                    }
                    restoreStartTimeout = timeout;
                    requiresRestoreAction.Add("restore-start-timeout");
                }},
				{"restore-defrag", 
					"Applicable only during restore, execute defrag after the restore is completed", key =>
					{
						defrag = true;
					    requiresRestoreAction.Add("restore-defrag");
					}},
				{"restore-destination=", "The {0:path} of the new database. If not specified it will be located in default data directory", value =>
				{
				    restoreLocation = value;
				    requiresRestoreAction.Add("restore-destination");
				}},
				{"restore-source=", "The {0:path} of the backup", value =>
				{
				    backupLocation = value;
				    requiresRestoreAction.Add("restore-source");
				}},
				{"restore-database-name=", "The {0:name} of the new database. If not specified, it will be extracted from backup. Only applicable during REMOTE restore", value =>
				{
				    restoreDatabaseName = value;
				    requiresRestoreAction.Add("restore-database-name");
				}},
                {"restore-filesystem-name", "The {0:name} of the new filesystem. If not specified, it will be extracted from backup.", value =>
                {
                    restoreFilesystemName = value;
                    requiresRestoreAction.Add("restore-filesystem-name");
                }},
				{"encrypt-self-config", "Encrypt the RavenDB configuration file", file =>
						{
							actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
						}},
				{"encrypt-config=", "Encrypt the specified {0:configuration file}", file =>
						{
							actionToTake = () => ProtectConfiguration(file);
						}},
				{"decrypt-self-config", "Decrypt the RavenDB configuration file", file =>
						{
							actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
						}},
				{"decrypt-config=", "Decrypt the specified {0:configuration file}", file =>
						{
							actionToTake = () => UnprotectConfiguration(file);
						}},
				{"installSSL={==}", "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
						{
							actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
						}},
				{"uninstallSSL={==}", "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
						{
							actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
						}},
                {"update-version=", "Updates the specified {0:databaseName} to newest version", dbName =>
                    {
                        actionToTake = () => UpdateVersion(dbName);
                    }}
			};


			try
			{
				if (args.Length == 0) // we default to executing in debug mode 
					args = new[] { "--debug" };

				optionSet.Parse(args);
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				PrintUsage(optionSet);
				return;
			}

            if (!isRestoreAction && requiresRestoreAction.Any())
            {
                var joinedActions = string.Join(", ", requiresRestoreAction);
                throw new OptionException(string.Format("when using {0}, --restore-source must be specified", joinedActions), joinedActions);
            }

			if (actionToTake == null)
				actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog);

			actionToTake();

		}
Пример #27
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                State = RestoreStatusState.Running, Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <DatabaseRestoreRequest>();

            DatabaseDocument databaseDocument = null;

            var databaseDocumentPath = MaintenanceActions.FindDatabaseDocument(restoreRequest.BackupLocation);

            if (File.Exists(databaseDocumentPath))
            {
                var databaseDocumentText = File.ReadAllText(databaseDocumentPath);
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id))
                                                                ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                                                : "A database name must be supplied if the restore location does not contain a valid Database.Document file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            if (databaseName == Constants.SystemDatabase)
            {
                return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest));
            }

            var existingDatabase = Database.Documents.GetDocumentMetadata("Raven/Databases/" + databaseName, null);

            if (existingDatabase != null)
            {
                return(GetMessageWithString("Cannot do an online restore for an existing database, delete the database " + databaseName + " and restore again.", HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (databaseDocument != null)
            {
                foreach (var setting in databaseDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename)))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForDatabaseTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);
            restoreRequest.DatabaseLocation  = ravenConfiguration.DataDirectory;

            string anotherRestoreResourceName;

            if (IsAnotherRestoreInProgress(out anotherRestoreResourceName))
            {
                if (restoreRequest.RestoreStartTimeout.HasValue)
                {
                    try
                    {
                        using (var cts = new CancellationTokenSource())
                        {
                            cts.CancelAfter(TimeSpan.FromSeconds(restoreRequest.RestoreStartTimeout.Value));
                            var token = cts.Token;
                            do
                            {
                                await Task.Delay(500, token);
                            }while (IsAnotherRestoreInProgress(out anotherRestoreResourceName));
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return(GetMessageWithString(string.Format("Another restore is still in progress (resource name = {0}). Waited {1} seconds for other restore to complete.", anotherRestoreResourceName, restoreRequest.RestoreStartTimeout.Value), HttpStatusCode.ServiceUnavailable));
                    }
                }
                else
                {
                    return(GetMessageWithString(string.Format("Another restore is in progress (resource name = {0})", anotherRestoreResourceName), HttpStatusCode.ServiceUnavailable));
                }
            }
            Database.Documents.Put(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, RavenJObject.FromObject(new RestoreInProgress
            {
                Resource = databaseName
            }), new RavenJObject(), null);

            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    MaintenanceActions.Restore(ravenConfiguration, restoreRequest,
                                               msg =>
                    {
                        restoreStatus.Messages.Add(msg);
                        DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                       RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    });

                    if (databaseDocument == null)
                    {
                        return;
                    }

                    databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
                    if (restoreRequest.IndexesLocation != null)
                    {
                        databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                    }
                    if (restoreRequest.JournalsLocation != null)
                    {
                        databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                    }

                    bool replicationBundleRemoved = false;
                    if (restoreRequest.DisableReplicationDestinations)
                    {
                        replicationBundleRemoved = TryRemoveReplicationBundle(databaseDocument);
                    }

                    databaseDocument.Id = databaseName;
                    DatabasesLandlord.Protect(databaseDocument);
                    DatabasesLandlord
                    .SystemDatabase
                    .Documents
                    .Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null);

                    restoreStatus.Messages.Add("The new database was created");
                    restoreStatus.State = RestoreStatusState.Completed;
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);

                    if (restoreRequest.GenerateNewDatabaseId)
                    {
                        GenerateNewDatabaseId(databaseName);
                    }

                    if (replicationBundleRemoved)
                    {
                        AddReplicationBundleAndDisableReplicationDestinations(databaseName);
                    }
                }
                catch (Exception e)
                {
                    restoreStatus.State = RestoreStatusState.Faulted;
                    restoreStatus.Messages.Add("Unable to restore database " + e.Message);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    throw;
                }
                finally
                {
                    Database.Documents.Delete(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, null);
                }
            }, TaskCreationOptions.LongRunning);

            long id;

            Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription
            {
                StartTime = SystemTime.UtcNow,
                TaskType  = TaskActions.PendingTaskType.RestoreDatabase,
                Payload   = "Restoring database " + databaseName + " from " + restoreRequest.BackupLocation
            }, out id);


            return(GetMessageWithObject(new
            {
                OperationId = id
            }));
        }
Пример #28
0
        public static void Main(string[] args)
        {
            string path          = string.Concat(Environment.CurrentDirectory, "\\settings.json");
            var    configuration = new RavenConfiguration(null, ResourceType.Server, path);

            configuration.Initialize();

            LoggingSource.Instance.SetupLogMode(configuration.Logs.Mode, configuration.Logs.Path.FullPath);
            if (Logger.IsInfoEnabled)
            {
                Logger.Info($"Logging to {configuration.Logs.Path} set to {configuration.Logs.Mode} level.");
            }

            if (Logger.IsOperationsEnabled)
            {
                Logger.Operations(RavenCli.GetInfoText());
            }

            RestartServer = () =>
            {
                ResetServerMre.Set();
                ShutdownServerMre.Set();
            };

            var rerun = false;
            RavenConfiguration configBeforeRestart = configuration;

            do
            {
                try
                {
                    using (var server = new RavenServer(configuration))
                    {
                        try
                        {
                            try
                            {
                                server.OpenPipes();
                            }
                            catch (Exception e)
                            {
                                if (Logger.IsInfoEnabled)
                                {
                                    Logger.Info("Unable to OpenPipe. Admin Channel will not be available to the user", e);
                                }
                                Console.WriteLine("Warning: Admin Channel is not available");
                            }

                            server.Initialize();

                            var prevColor = Console.ForegroundColor;
                            Console.Write("Server available on: ");
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.WriteLine($"{server.ServerStore.GetNodeHttpServerUrl()}");
                            Console.ForegroundColor = prevColor;

                            var tcpServerStatus = server.GetTcpServerStatus();
                            prevColor = Console.ForegroundColor;
                            Console.Write("Tcp listening on ");
                            Console.ForegroundColor = ConsoleColor.Green;
                            Console.WriteLine($"{string.Join(", ", tcpServerStatus.Listeners.Select(l => l.LocalEndpoint))}");
                            Console.ForegroundColor = prevColor;

                            IsRunningNonInteractive = false;

                            Console.WriteLine("Server start completed");

                            Console.ReadLine();

                            Console.WriteLine("Starting shut down...");
                            if (Logger.IsInfoEnabled)
                            {
                                Logger.Info("Server is shutting down");
                            }
                        }
                        catch (Exception e)
                        {
                            if (Logger.IsOperationsEnabled)
                            {
                                Logger.Operations("Failed to initialize the server", e);
                            }
                            Console.WriteLine(e);
                        }
                    }

                    Console.WriteLine("Shutdown completed");
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error during shutdown");
                    Console.WriteLine(e);
                }
                finally
                {
                    if (Logger.IsOperationsEnabled)
                    {
                        Logger.OperationsAsync("Server has shut down").Wait(TimeSpan.FromSeconds(15));
                    }
                }
            } while (rerun);
        }
Пример #29
0
		private static void InteractiveRun(string[] args)
		{
			var ioTestRequest = new GenericPerformanceTestRequest();

			string backupLocation = null;
			string restoreLocation = null;
			string restoreDatabaseName = null;
			string restoreFilesystemName = null;
			bool restoreDisableReplication = false;
			bool defrag = false;
			var requiresRestoreAction = new HashSet<string>();
			bool isRestoreAction = false;
			var requiresIoTestAction = new HashSet<string>();
			bool isIoTestAction = false;
			Action actionToTake = null;
			bool launchBrowser = false;
			bool noLog = false;
			var ravenConfiguration = new RavenConfiguration();
			bool waitForRestore = true;
			int? restoreStartTimeout = 15;

			var optionSet = new OptionSet();
			optionSet.Add("set={==}", OptionCategory.None, "The configuration {0:option} to set to the specified {1:value}", (key, value) =>
			{
				ravenConfiguration.Settings[key] = value;
				ravenConfiguration.Initialize();
			});
			optionSet.Add("nolog", OptionCategory.General, "Don't use the default log", s => noLog = true);
			optionSet.Add("config=", OptionCategory.General, "The config {0:file} to use", ravenConfiguration.LoadFrom);
			optionSet.Add("install", OptionCategory.Service, "Installs the RavenDB service", key => actionToTake = () => AdminRequired(InstallAndStart));
			optionSet.Add("allow-blank-password-use", OptionCategory.Other, "Allow to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(0)));
			optionSet.Add("deny-blank-password-use", OptionCategory.Other, "Deny to log on by using a Windows account that has a blank password", key => actionToTake = () => AdminRequired(() => SetLimitBlankPasswordUseRegValue(1)));
			optionSet.Add("service-name=", OptionCategory.Service, "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name);
			optionSet.Add("uninstall", OptionCategory.Service, "Uninstalls the RavenDB service", key => actionToTake = () => AdminRequired(EnsureStoppedAndUninstall));
			optionSet.Add("start", OptionCategory.Service, "Starts the RavenDB service", key => actionToTake = () => AdminRequired(StartService));
			optionSet.Add("restart", OptionCategory.Service, "Restarts the RavenDB service", key => actionToTake = () => AdminRequired(RestartService));
			optionSet.Add("stop", OptionCategory.Service, "Stops the RavenDB service", key => actionToTake = () => AdminRequired(StopService));
			optionSet.Add("ram", OptionCategory.General, "Run RavenDB in RAM only", key =>
			{
                ravenConfiguration.Settings[Constants.RunInMemory] = "true";
				ravenConfiguration.RunInMemory = true;
				ravenConfiguration.Initialize();
				actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.Admin, ravenConfiguration, launchBrowser, noLog);
			});
			optionSet.Add("debug", OptionCategory.General, "Run RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog));
			optionSet.Add("browser|launchbrowser", OptionCategory.General, "After the server starts, launches the browser", key => launchBrowser = true);
			optionSet.Add("help", OptionCategory.Help, "Help about the command line interface", key =>
			{
				actionToTake = () => PrintUsage(optionSet);
			});
			optionSet.Add("config-help", OptionCategory.Help, "Help about configuration databaseOptions", key =>
			{
				actionToTake = () => PrintConfig(ravenConfiguration.GetConfigOptionsDocs());
			});
			optionSet.Add("restore", OptionCategory.RestoreDatabase, "[Obsolete] Use --restore-system-database or --restore-database", key =>
			{
				actionToTake = () =>
				{
					throw new OptionException("This method is obsolete, use --restore-system-database or --restore-database", "restore");
				};
				isRestoreAction = true;
			});
			optionSet.Add("restore-system-database", OptionCategory.RestoreDatabase, "Restores a SYSTEM database from backup.", key =>
			{
				actionToTake = () =>
				{
					if (backupLocation == null || restoreLocation == null)
					{
						throw new OptionException("When using --restore-system-database, --restore-source and --restore-destination must be specified", "restore-system-database");
					}
					RunSystemDatabaseRestoreOperation(backupLocation, restoreLocation, defrag);
				};
				isRestoreAction = true;
			});
			optionSet.Add("restore-database=", OptionCategory.RestoreDatabase, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url =>
			{
				actionToTake = () =>
				{
					if (backupLocation == null)
					{
						throw new OptionException("When using --restore-database, --restore-source must be specified", "restore-database");
					}

					Uri uri;
					if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false)
					{
						throw new OptionException("Specified destination server url is not valid", "restore-database");
					}

					RunRemoteDatabaseRestoreOperation(backupLocation, restoreLocation, restoreDatabaseName, defrag, restoreDisableReplication, uri, waitForRestore, restoreStartTimeout);
					Environment.Exit(0);
				};
				isRestoreAction = true;
			});
			optionSet.Add("restore-filesystem=", OptionCategory.RestoreFileSystem, "Starts a restore operation from a backup on a REMOTE server found under specified {0:url}.", url =>
			{
				actionToTake = () =>
				{
					if (backupLocation == null)
					{
						throw new OptionException("When using --restore-filesystem, --restore-source must be specified", "restore-filesystem");
					}

					Uri uri;
					if (Uri.TryCreate(url, UriKind.Absolute, out uri) == false)
					{
						throw new OptionException("Specified destination server url is not valid", "restore-database");
					}

					RunRemoteFilesystemRestoreOperation(backupLocation, restoreLocation, restoreFilesystemName, defrag, uri, waitForRestore, restoreStartTimeout);
					Environment.Exit(0);
				};
				isRestoreAction = true;
			});
			optionSet.Add("restore-disable-replication", OptionCategory.RestoreDatabase, "Disables replication destinations in newly restored database", value =>
			{
				restoreDisableReplication = true;
				requiresRestoreAction.Add("restore-disable-replication");
			});
			optionSet.Add("restore-no-wait", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Return immediately without waiting for a restore to complete", value =>
			{
				waitForRestore = false;
				requiresRestoreAction.Add("restore-no-wait");
			});
			optionSet.Add("restore-start-timeout=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The maximum {0:timeout} in seconds to wait for another restore to complete. Default: 15 seconds.", value =>
			{
				int timeout;
				if (int.TryParse(value, out timeout) == false)
				{
					throw new OptionException("Specified restore start timeout is not valid", "restore-start-timeout");
				}
				restoreStartTimeout = timeout;
				requiresRestoreAction.Add("restore-start-timeout");
			});
			optionSet.Add("restore-defrag", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "Applicable only during restore, execute defrag after the restore is completed", key =>
			{
				defrag = true;
				requiresRestoreAction.Add("restore-defrag");
			});
			optionSet.Add("restore-destination=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the new database. If not specified it will be located in default data directory", value =>
			{
				restoreLocation = value;
				requiresRestoreAction.Add("restore-destination");
			});
			optionSet.Add("restore-source=", OptionCategory.RestoreDatabase | OptionCategory.RestoreFileSystem, "The {0:path} of the backup", value =>
			{
				backupLocation = value;
				requiresRestoreAction.Add("restore-source");
			});
			optionSet.Add("restore-database-name=", OptionCategory.RestoreDatabase, "The {0:name} of the new database. If not specified, it will be extracted from backup. Only applicable during REMOTE restore", value =>
			{
				restoreDatabaseName = value;
				requiresRestoreAction.Add("restore-database-name");
			});
			optionSet.Add("restore-filesystem-name", OptionCategory.RestoreFileSystem, "The {0:name} of the new filesystem. If not specified, it will be extracted from backup.", value =>
			{
				restoreFilesystemName = value;
				requiresRestoreAction.Add("restore-filesystem-name");
			});
			optionSet.Add("io-test=", OptionCategory.IOTest, "Performs disk io test using {0:dir} as temporary dir path", path =>
			{
				ioTestRequest.Path = path;
				actionToTake = () => IoTest(ioTestRequest);
				isIoTestAction = true;
			});
			optionSet.Add("io-test-file-size=", OptionCategory.IOTest, "The {0:size} of test file for io test in MB (default: 1024MB)", value =>
			{
				int fileSize;
				if (int.TryParse(value, out fileSize) == false)
				{
					throw new OptionException("Specified test file size is not valid", "io-test-file-size");
				}
				ioTestRequest.FileSize = fileSize * 1024 * 1024;
				requiresIoTestAction.Add("io-test-file-size");
			});
			optionSet.Add("io-test-threads=", OptionCategory.IOTest, "The {0:number} of threads to use during test", value =>
			{
				int threads;
				if (int.TryParse(value, out threads) == false)
				{
					throw new OptionException("Specified amount of threads is not valid", "io-test-threads");
				}
				ioTestRequest.ThreadCount = threads;
				requiresIoTestAction.Add("io-test-threads");
			});
			optionSet.Add("io-test-time=", OptionCategory.IOTest, "The {0:number} of seconds to run the test (default: 30)", value =>
			{
				int testTime;
				if (int.TryParse(value, out testTime) == false)
				{
					throw new OptionException("Specified test time is not valid", "io-test-time");
				}
				ioTestRequest.TimeToRunInSeconds = testTime;
				requiresIoTestAction.Add("io-test-time");
			});
			optionSet.Add("io-test-seed=", OptionCategory.IOTest, "The {0:seed} for random generator", value =>
			{
				int seed;
				if (int.TryParse(value, out seed) == false)
				{
					throw new OptionException("Specified random seed is not valid", "io-test-seed");
				}
				ioTestRequest.RandomSeed = seed;
				requiresIoTestAction.Add("io-test-seed");
			});
			optionSet.Add("io-test-mode=", OptionCategory.IOTest, "The operation {0:mode} (read,write,mix) (default: write)", value =>
			{
				OperationType opType;
				if (Enum.TryParse(value, true, out opType) == false)
				{
					throw new OptionException("Specified test mode is not valid", "io-test-mode");
				}
				ioTestRequest.OperationType = opType;
				requiresIoTestAction.Add("io-test-mode");
			});
			optionSet.Add("io-test-chunk-size=", OptionCategory.IOTest, "The {0:value} for chunk size in KB (default: 4 KB)", value =>
			{
				int chunkSize;
				if (int.TryParse(value, out chunkSize) == false)
				{
					throw new OptionException("Specified test chunk size is not valid", "io-test-chunk-size");
				}
				ioTestRequest.ChunkSize = chunkSize * 1024;
				requiresIoTestAction.Add("io-test-chunk-size");
			});
			optionSet.Add("io-test-sequential", OptionCategory.IOTest, "Perform sequential read/write (default: random)", value =>
			{
				ioTestRequest.Sequential = true;
				requiresIoTestAction.Add("io-test-sequential");
			});
			optionSet.Add("io-test-buffering-type", OptionCategory.IOTest, "Buffering type (None,Read, ReadAndWrite) (default: None)", value =>
			{
				BufferingType bufferingType;
				if (Enum.TryParse(value, true, out bufferingType) == false)
				{
					throw new OptionException("Specified buffering type is not valid", "io-test-buffering-type");
				}
				ioTestRequest.BufferingType = bufferingType;
				requiresIoTestAction.Add("io-test-buffering-type");
			});
			optionSet.Add("encrypt-self-config", OptionCategory.Encryption, "Encrypt the RavenDB configuration file", file =>
			{
				actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
			});
			optionSet.Add("encrypt-config=", OptionCategory.Encryption, "Encrypt the specified {0:configuration file}", file =>
			{
				actionToTake = () => ProtectConfiguration(file);
			});
			optionSet.Add("decrypt-self-config", OptionCategory.Encryption, "Decrypt the RavenDB configuration file", file =>
			{
				actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
			});
			optionSet.Add("decrypt-config=", OptionCategory.Encryption, "Decrypt the specified {0:configuration file}", file =>
			{
				actionToTake = () => UnprotectConfiguration(file);
			});
			optionSet.Add("installSSL={==}", OptionCategory.SSL, "Bind X509 certificate specified in {0:option} with optional password from {1:option} with 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
			{
				actionToTake = () => InstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
			});
			optionSet.Add("uninstallSSL={==}", OptionCategory.SSL, "Unbind X509 certificate specified in {0:option} with optional password from {2:option} from 'Raven/Port'.", (sslCertificateFile, sslCertificatePassword) =>
			{
				actionToTake = () => UninstallSsl(sslCertificateFile, sslCertificatePassword, ravenConfiguration);
			});
			optionSet.Add("update-version=", OptionCategory.Update, "Updates the specified {0:databaseName} to newest version", dbName =>
			{
				actionToTake = () => UpdateVersion(dbName);
			});

			try
			{
				if (args.Length == 0) // we default to executing in debug mode 
					args = new[] { "--debug" };

				optionSet.Parse(args);
			}
			catch (Exception e)
			{
				ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message);
				PrintUsage(optionSet);
				ConsoleWriteLineWithColor(ConsoleColor.Red, e.Message);
				Environment.Exit(-1);
				return;
			}

			if (!isRestoreAction && requiresRestoreAction.Any())
			{
				var joinedActions = string.Join(", ", requiresRestoreAction);
				throw new OptionException(string.Format("When using {0}, --restore-source must be specified", joinedActions), joinedActions);
			}

			if (!isIoTestAction && requiresIoTestAction.Any())
			{
				var joinedActions = string.Join(", ", requiresRestoreAction);
				throw new OptionException(string.Format("When using {0}, --io-test must be specified", joinedActions), joinedActions);
			}

			if (actionToTake == null)
				actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser, noLog);

			actionToTake();
		}
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <FilesystemRestoreRequest>();

            FileSystemDocument filesystemDocument = null;

            var fileSystemDocumentPath = FindFilesystemDocument(restoreRequest.BackupLocation);

            if (!File.Exists(fileSystemDocumentPath))
            {
                throw new InvalidOperationException("Cannot restore when the Filesystem.Document file is missing in the backup folder: " + restoreRequest.BackupLocation);
            }

            var filesystemDocumentText = File.ReadAllText(fileSystemDocumentPath);

            filesystemDocument = RavenJObject.Parse(filesystemDocumentText).JsonDeserialization <FileSystemDocument>();

            var filesystemName = !string.IsNullOrWhiteSpace(restoreRequest.FilesystemName) ? restoreRequest.FilesystemName
                                   : filesystemDocument == null ? null : filesystemDocument.Id;

            if (string.IsNullOrWhiteSpace(filesystemName))
            {
                var errorMessage = (filesystemDocument == null || String.IsNullOrWhiteSpace(filesystemDocument.Id))
                                ? BackupMethods.FilesystemDocumentFilename + " file is invalid - filesystem name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                : "A filesystem name must be supplied if the restore location does not contain a valid " + BackupMethods.FilesystemDocumentFilename + " file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = filesystemName,
                IsTenantDatabase = true
            };

            if (filesystemDocument != null)
            {
                foreach (var setting in filesystemDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename)))
            {
                ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.VoronTypeName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.EsentTypeName;
            }

            ravenConfiguration.CustomizeValuesForTenant(filesystemName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.FileSystem.DataDirectory = ResolveTenantDataDirectory(restoreRequest.FilesystemLocation, filesystemName, out documentDataDir);
            restoreRequest.FilesystemLocation           = ravenConfiguration.FileSystem.DataDirectory;

            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            //TODO: add task to pending task list like in ImportDatabase
            Task.Factory.StartNew(() =>
            {
                if (!string.IsNullOrWhiteSpace(restoreRequest.FilesystemLocation))
                {
                    ravenConfiguration.FileSystem.DataDirectory = restoreRequest.FilesystemLocation;
                }

                using (var transactionalStorage = RavenFileSystem.CreateTransactionalStorage(ravenConfiguration))
                {
                    transactionalStorage.Restore(restoreRequest, msg =>
                    {
                        restoreStatus.Messages.Add(msg);
                        DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null,
                                                                       RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    });
                }

                if (filesystemDocument == null)
                {
                    return;
                }

                filesystemDocument.Settings["Raven/FileSystem/DataDir"] = documentDataDir;
                if (restoreRequest.IndexesLocation != null)
                {
                    filesystemDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                }
                if (restoreRequest.JournalsLocation != null)
                {
                    filesystemDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                }
                filesystemDocument.Id = filesystemName;
                DatabasesLandlord.SystemDatabase.Documents.Put("Raven/FileSystems/" + filesystemName, null, RavenJObject.FromObject(filesystemDocument),
                                                               new RavenJObject(), null);

                restoreStatus.Messages.Add("The new filesystem was created");
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null,
                                                               RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
            }, TaskCreationOptions.LongRunning);

            return(GetEmptyMessage());
        }
Пример #31
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                State = RestoreStatusState.Running, Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <FilesystemRestoreRequest>();

            var fileSystemDocumentPath = FindFilesystemDocument(restoreRequest.BackupLocation);

            if (!File.Exists(fileSystemDocumentPath))
            {
                throw new InvalidOperationException("Cannot restore when the Filesystem.Document file is missing in the backup folder: " + restoreRequest.BackupLocation);
            }

            var filesystemDocumentText = File.ReadAllText(fileSystemDocumentPath);
            var filesystemDocument     = RavenJObject.Parse(filesystemDocumentText).JsonDeserialization <FileSystemDocument>();

            var filesystemName = !string.IsNullOrWhiteSpace(restoreRequest.FilesystemName) ? restoreRequest.FilesystemName
                                   : filesystemDocument == null ? null : filesystemDocument.Id;

            if (string.IsNullOrWhiteSpace(filesystemName))
            {
                var errorMessage = (filesystemDocument == null || String.IsNullOrWhiteSpace(filesystemDocument.Id))
                                ? Constants.FilesystemDocumentFilename + " file is invalid - filesystem name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                : "A filesystem name must be supplied if the restore location does not contain a valid " + Constants.FilesystemDocumentFilename + " file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                FileSystemName = filesystemName,
            };

            if (filesystemDocument != null)
            {
                foreach (var setting in filesystemDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.EsentTypeName;
            }
            else
            {
                ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.VoronTypeName;
            }

            ravenConfiguration.CustomizeValuesForFileSystemTenant(filesystemName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.FileSystem.DataDirectory = ResolveTenantDataDirectory(restoreRequest.FilesystemLocation, filesystemName, out documentDataDir);
            restoreRequest.FilesystemLocation           = ravenConfiguration.FileSystem.DataDirectory;


            string anotherRestoreResourceName;

            if (IsAnotherRestoreInProgress(out anotherRestoreResourceName))
            {
                if (restoreRequest.RestoreStartTimeout.HasValue)
                {
                    try
                    {
                        using (var cts = new CancellationTokenSource())
                        {
                            cts.CancelAfter(TimeSpan.FromSeconds(restoreRequest.RestoreStartTimeout.Value));
                            var token = cts.Token;
                            do
                            {
                                await Task.Delay(500, token);
                            }while (IsAnotherRestoreInProgress(out anotherRestoreResourceName));
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return(GetMessageWithString(string.Format("Another restore is still in progress (resource name = {0}). Waited {1} seconds for other restore to complete.", anotherRestoreResourceName, restoreRequest.RestoreStartTimeout.Value), HttpStatusCode.ServiceUnavailable));
                    }
                }
                else
                {
                    return(GetMessageWithString(string.Format("Another restore is in progress (resource name = {0})", anotherRestoreResourceName), HttpStatusCode.ServiceUnavailable));
                }
            }
            Database.Documents.Put(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, RavenJObject.FromObject(new RestoreInProgress
            {
                Resource = filesystemName
            }), new RavenJObject(), null);

            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(restoreRequest.FilesystemLocation))
                    {
                        ravenConfiguration.FileSystem.DataDirectory = restoreRequest.FilesystemLocation;
                    }

                    using (var transactionalStorage = RavenFileSystem.CreateTransactionalStorage(ravenConfiguration))
                    {
                        transactionalStorage.Restore(restoreRequest, msg =>
                        {
                            restoreStatus.Messages.Add(msg);
                            DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null,
                                                                           RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                        });
                    }

                    if (filesystemDocument == null)
                    {
                        return;
                    }

                    filesystemDocument.Settings[Constants.FileSystem.DataDirectory] = documentDataDir;

                    if (restoreRequest.IndexesLocation != null)
                    {
                        filesystemDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                    }
                    if (restoreRequest.JournalsLocation != null)
                    {
                        filesystemDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                    }
                    filesystemDocument.Id = filesystemName;

                    FileSystemsLandlord.Protect(filesystemDocument);

                    DatabasesLandlord.SystemDatabase.Documents.Put(Constants.FileSystem.Prefix + filesystemName, null, RavenJObject.FromObject(filesystemDocument), new RavenJObject(), null);

                    restoreStatus.State = RestoreStatusState.Completed;
                    restoreStatus.Messages.Add("The new filesystem was created");
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                }
                catch (Exception e)
                {
                    restoreStatus.State = RestoreStatusState.Faulted;
                    restoreStatus.Messages.Add("Unable to restore filesystem " + e.Message);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    throw;
                }
                finally
                {
                    Database.Documents.Delete(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, null);
                }
            }, TaskCreationOptions.LongRunning);

            long id;

            Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription
            {
                StartTime = SystemTime.UtcNow,
                TaskType  = TaskActions.PendingTaskType.RestoreFilesystem,
                Payload   = "Restoring filesystem " + filesystemName + " from " + restoreRequest.BackupLocation
            }, out id);

            return(GetMessageWithObject(new
            {
                OperationId = id
            }));
        }
Пример #32
0
		private static void InteractiveRun(string[] args)
		{
			string backupLocation = null;
			string restoreLocation = null;
			Action actionToTake = null;
			bool launchBrowser = false;
			var ravenConfiguration = new RavenConfiguration();

			OptionSet optionSet = null;
			optionSet = new OptionSet
			{
				{"set={==}", "The configuration {0:option} to set to the specified {1:value}" , (key, value) =>
				{
					ravenConfiguration.Settings[key] = value;
					ravenConfiguration.Initialize();
				}},
				{"config=", "The config {0:file} to use", path => ravenConfiguration.LoadFrom(path)},
				{"install", "Installs the RavenDB service", key => actionToTake= () => AdminRequired(InstallAndStart, key)},
				{"service-name=", "The {0:service name} to use when installing or uninstalling the service, default to RavenDB", name => ProjectInstaller.SERVICE_NAME = name},
				{"uninstall", "Uninstalls the RavenDB service", key => actionToTake= () => AdminRequired(EnsureStoppedAndUninstall, key)},
				{"start", "Starts the RavenDB service", key => actionToTake= () => AdminRequired(StartService, key)},
				{"restart", "Restarts the RavenDB service", key => actionToTake= () => AdminRequired(RestartService, key)},
				{"stop", "Stops the RavenDB service", key => actionToTake= () => AdminRequired(StopService, key)},
				{"ram", "Run RavenDB in RAM only", key =>
				{
					ravenConfiguration.Settings["Raven/RunInMemory"] = "true";
					ravenConfiguration.RunInMemory = true;
					actionToTake = () => RunInDebugMode(AnonymousUserAccessMode.All, ravenConfiguration, launchBrowser);		
				}},
				{"debug", "Runs RavenDB in debug mode", key => actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser)},
				{"browser|launchbrowser", "After the server starts, launches the browser", key => launchBrowser = true},
				{"help", "Help about the command line interface", key =>
				{
					actionToTake = () => PrintUsage(optionSet);
				}},
				{"config-help", "Help about configuration options", key=>
				{
					actionToTake = PrintConfig;
				}},
				{"restore", 
					"Restores a RavenDB database from backup",
					key => actionToTake = () =>
					{
						if(backupLocation == null || restoreLocation == null)
						{
							throw new OptionException("when using restore, source and destination must be specified", "restore");
						}
						RunRestoreOperation(backupLocation, restoreLocation);
					}},
				{"dest=|destination=", "The {0:path} of the new new database", value => restoreLocation = value},
				{"src=|source=", "The {0:path} of the backup", value => backupLocation = value},
				{"encrypt-self-config", "Encrypt the RavenDB configuration file", file =>
						{
							actionToTake = () => ProtectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
				        }},
				{"encrypt-config=", "Encrypt the specified {0:configuration file}", file =>
						{
							actionToTake = () => ProtectConfiguration(file);
				        }},
				{"decrypt-self-config", "Decrypt the RavenDB configuration file", file =>
						{
							actionToTake = () => UnprotectConfiguration(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
				        }},
				{"decrypt-config=", "Decrypt the specified {0:configuration file}", file =>
						{
							actionToTake = () => UnprotectConfiguration(file);
				        }}
			};


			try
			{
				if (args.Length == 0) // we default to executing in debug mode 
					args = new[] { "--debug" };

				optionSet.Parse(args);
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
				PrintUsage(optionSet);
				return;
			}

			if (actionToTake == null)
				actionToTake = () => RunInDebugMode(null, ravenConfiguration, launchBrowser);

			actionToTake();

		}
Пример #33
0
        public override void RespondToAdmin(IHttpContext context)
        {
            if (EnsureSystemDatabase(context) == false)
            {
                return;
            }

            var restoreRequest = context.ReadJsonObject <RestoreRequest>();

            DatabaseDocument databaseDocument = null;

            if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Database.Document")))
            {
                var databaseDocumentText = File.ReadAllText(Path.Combine(restoreRequest.RestoreLocation, "Database.Document"));
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                context.SetStatusToBadRequest();
                context.WriteJson(new
                {
                    Error = "A database name must be supplied if the restore location does not contain a valid Database.Document file"
                });
                return;
            }

            var ravenConfiguration = new RavenConfiguration()
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Raven.ravendb")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Managed.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.RestoreLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);

            var restoreStatus = new List <string>();

            SystemDatabase.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, new TransactionInformation());
            DocumentDatabase.Restore(ravenConfiguration, restoreRequest.RestoreLocation, null,
                                     msg =>
            {
                restoreStatus.Add(msg);
                SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                   RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);
            });

            if (databaseDocument == null)
            {
                return;
            }

            databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
            databaseDocument.Id = databaseName;
            SystemDatabase.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null);

            restoreStatus.Add("The new database was created");
            SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                               RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);
        }
Пример #34
0
        public override void RespondToAdmin(IHttpContext context)
        {
            if (EnsureSystemDatabase(context) == false)
            {
                return;
            }

            var restoreRequest = context.ReadJsonObject <RestoreRequest>();
            var restoreStatus  = new List <string>();

            SystemDatabase.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null);

            DatabaseDocument databaseDocument = null;

            if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Database.Document")))
            {
                var databaseDocumentText = File.ReadAllText(Path.Combine(restoreRequest.RestoreLocation, "Database.Document"));
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                context.SetStatusToBadRequest();

                var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id))
                                        ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                        : "A database name must be supplied if the restore location does not contain a valid Database.Document file";

                context.WriteJson(new
                {
                    Error = errorMessage
                });

                restoreStatus.Add(errorMessage);
                SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                   RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return;
            }

            if (databaseName == Constants.SystemDatabase)
            {
                context.SetStatusToBadRequest();
                context.WriteJson(new
                {
                    Error = "Cannot do an online restore for the <system> database"
                });

                restoreStatus.Add("Cannot do an online restore for the <system> database");
                SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                   RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);
                return;
            }


            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (databaseDocument != null)
            {
                foreach (var setting in databaseDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.RestoreLocation, "Raven.ravendb")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Managed.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.RestoreLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);


            var defrag = "true".Equals(context.Request.QueryString["defrag"], StringComparison.InvariantCultureIgnoreCase);

            Task.Factory.StartNew(() =>
            {
                DocumentDatabase.Restore(ravenConfiguration, restoreRequest.RestoreLocation, null,
                                         msg =>
                {
                    restoreStatus.Add(msg);
                    SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                       RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);
                }, defrag);

                if (databaseDocument == null)
                {
                    restoreStatus.Add("Restore ended but could not create the datebase document, in order to access the data create a database with the appropriate name");
                    SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                       RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);
                    return;
                }

                databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
                databaseDocument.Id = databaseName;
                server.Protect(databaseDocument);
                SystemDatabase.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument),
                                   new RavenJObject(), null);

                restoreStatus.Add("The new database was created");
                SystemDatabase.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                   RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);
            }, TaskCreationOptions.LongRunning);
        }