Ejemplo n.º 1
0
 private void UploadToGlacier(string backupPath, PeriodicExportSetup localExportConfigs, bool isFullBackup)
 {
     if (awsAccessKey == Constants.DataCouldNotBeDecrypted ||
         awsSecretKey == Constants.DataCouldNotBeDecrypted)
     {
         throw new InvalidOperationException("Could not decrypt the AWS access settings, if you are running on IIS, make sure that load user profile is set to true.");
     }
     using (var client = new RavenAwsGlacierClient(awsAccessKey, awsSecretKey, localExportConfigs.AwsRegionEndpoint ?? RavenAwsClient.DefaultRegion))
         using (var fileStream = File.OpenRead(backupPath))
         {
             var archiveId = client.UploadArchive(localExportConfigs.GlacierVaultName, fileStream, GetArchiveDescription(isFullBackup), 60 * 60);
             logger.Info(string.Format("Successfully uploaded backup {0} to Glacier, archive ID: {1}", Path.GetFileName(backupPath), archiveId));
         }
 }
Ejemplo n.º 2
0
 private void UploadToServer(string backupPath, PeriodicExportSetup localExportConfigs, bool isFullBackup)
 {
     if (!string.IsNullOrWhiteSpace(localExportConfigs.GlacierVaultName))
     {
         UploadToGlacier(backupPath, localExportConfigs, isFullBackup);
     }
     else if (!string.IsNullOrWhiteSpace(localExportConfigs.S3BucketName))
     {
         UploadToS3(backupPath, localExportConfigs, isFullBackup);
     }
     else if (!string.IsNullOrWhiteSpace(localExportConfigs.AzureStorageContainer))
     {
         UploadToAzure(backupPath, localExportConfigs, isFullBackup);
     }
 }
Ejemplo n.º 3
0
        private void UploadToS3(string backupPath, PeriodicExportSetup localExportConfigs, bool isFullBackup)
        {
            using (var client = new RavenAwsS3Client(awsAccessKey, awsSecretKey, localExportConfigs.AwsRegionEndpoint ?? RavenAwsClient.DefaultRegion))
                using (var fileStream = File.OpenRead(backupPath))
                {
                    var key = Path.GetFileName(backupPath);
                    client.PutObject(localExportConfigs.S3BucketName, key, fileStream, new Dictionary <string, string>
                    {
                        { "Description", GetArchiveDescription(isFullBackup) }
                    }, 60 * 60);

                    logger.Info(string.Format("Successfully uploaded backup {0} to S3 bucket {1}, with key {2}",
                                              Path.GetFileName(backupPath), localExportConfigs.S3BucketName, key));
                }
        }
Ejemplo n.º 4
0
        public void CanBackupToDirectory()
        {
            var backupPath = NewDataPath("BackupFolder");

            try
            {
                using (var store = NewDocumentStore())
                {
                    using (var session = store.OpenSession())
                    {
                        session.Store(new User {
                            Name = "oren"
                        });
                        var periodicBackupSetup = new PeriodicExportSetup
                        {
                            LocalFolderName      = backupPath,
                            IntervalMilliseconds = 25
                        };
                        session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                        session.SaveChanges();
                    }
                    SpinWait.SpinUntil(() => store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey) != null, 10000);
                }

                using (var store = NewDocumentStore())
                {
                    var actualBackupPath   = Directory.GetDirectories(backupPath)[0];
                    var fullBackupFilePath = Directory.GetFiles(actualBackupPath).FirstOrDefault(x => x.Contains("full"));
                    Assert.NotNull(fullBackupFilePath);

                    // import the full backup
                    var dataDumper = new DatabaseDataDumper(store.SystemDatabase);
                    dataDumper.ImportData(new SmugglerImportOptions <RavenConnectionStringOptions> {
                        FromFile = fullBackupFilePath
                    }).Wait();

                    using (var session = store.OpenSession())
                    {
                        Assert.Equal("oren", session.Load <User>(1).Name);
                    }
                }
            }
            finally
            {
                IOExtensions.DeleteDirectory(backupPath);
            }
        }
Ejemplo n.º 5
0
        public void CanBackupAttachmentDeletion()
        {
            var backupPath = NewDataPath("BackupFolder");

            using (var store = NewDocumentStore())
            {
                string userId;
                using (var session = store.OpenSession())
                {
                    var periodicBackupSetup = new PeriodicExportSetup
                    {
                        LocalFolderName      = backupPath,
                        IntervalMilliseconds = 250
                    };
                    session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                    session.SaveChanges();
                }

                var backupStatus = GetPerodicBackupStatus(store.DocumentDatabase);

                store.DatabaseCommands.PutAttachment("attach/1", null, new MemoryStream(new byte[] { 1, 2, 3, 4 }), new RavenJObject());

                WaitForPeriodicExport(store.DocumentDatabase, backupStatus);

                store.DatabaseCommands.DeleteAttachment("attach/1", null);

                WaitForPeriodicExport(store.DocumentDatabase, backupStatus);
            }

            using (var store = NewDocumentStore())
            {
                var dataDumper = new DataDumper(store.DocumentDatabase);
                dataDumper.ImportData(new SmugglerImportOptions
                {
                    FromFile = backupPath,
                }, new SmugglerOptions
                {
                    Incremental = true,
                }).Wait();

                Assert.Null(store.DatabaseCommands.GetAttachment("attach/1"));
            }

            IOExtensions.DeleteDirectory(backupPath);
        }
Ejemplo n.º 6
0
        private void UploadToS3(string backupPath, PeriodicExportSetup localExportConfigs, bool isFullBackup)
        {
            if (awsAccessKey == Constants.DataCouldNotBeDecrypted ||
                awsSecretKey == Constants.DataCouldNotBeDecrypted)
            {
                throw new InvalidOperationException("Could not decrypt the AWS access settings, if you are running on IIS, make sure that load user profile is set to true.");
            }
            using (var client = new RavenAwsS3Client(awsAccessKey, awsSecretKey, localExportConfigs.AwsRegionEndpoint ?? RavenAwsClient.DefaultRegion))
                using (var fileStream = File.OpenRead(backupPath))
                {
                    var key = Path.GetFileName(backupPath);
                    client.PutObject(localExportConfigs.S3BucketName, key, fileStream, new Dictionary <string, string>
                    {
                        { "Description", GetArchiveDescription(isFullBackup) }
                    }, 60 * 60);

                    logger.Info(string.Format("Successfully uploaded backup {0} to S3 bucket {1}, with key {2}",
                                              Path.GetFileName(backupPath), localExportConfigs.S3BucketName, key));
                }
        }
Ejemplo n.º 7
0
        public void CanBackupToDirectory()
        {
            var backupPath = NewDataPath("BackupFolder");

            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "oren"
                    });
                    var periodicBackupSetup = new PeriodicExportSetup
                    {
                        LocalFolderName      = backupPath,
                        IntervalMilliseconds = 25
                    };
                    session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                    session.SaveChanges();
                }
                SpinWait.SpinUntil(() => store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey) != null, 10000);
            }

            using (var store = NewDocumentStore())
            {
                var dataDumper = new DataDumper(store.DocumentDatabase);
                dataDumper.ImportData(new SmugglerImportOptions
                {
                    FromFile = backupPath,
                }, new SmugglerOptions
                {
                    Incremental = true,
                }).Wait();

                using (var session = store.OpenSession())
                {
                    Assert.Equal("oren", session.Load <User>(1).Name);
                }
            }
            IOExtensions.DeleteDirectory(backupPath);
        }
Ejemplo n.º 8
0
        private void UploadToAzure(string backupPath, PeriodicExportSetup localExportConfigs, bool isFullBackup)
        {
            using (var client = new RavenAzureClient(azureStorageAccount, azureStorageKey, true))
            {
                client.PutContainer(localExportConfigs.AzureStorageContainer);
                using (var fileStream = File.OpenRead(backupPath))
                {
                    var key = Path.GetFileName(backupPath);
                    client.PutBlob(localExportConfigs.AzureStorageContainer, key, fileStream, new Dictionary <string, string>
                    {
                        { "Description", GetArchiveDescription(isFullBackup) }
                    });

                    logger.Info(string.Format(
                                    "Successfully uploaded backup {0} to Azure container {1}, with key {2}",
                                    Path.GetFileName(backupPath),
                                    localExportConfigs.AzureStorageContainer,
                                    key));
                }
            }
        }
Ejemplo n.º 9
0
        private void ReadSetupValuesFromDocument()
        {
            using (LogContext.WithDatabase(Database.Name))
            {
                try
                {
                    // Not having a setup doc means this DB isn't enabled for periodic exports
                    var document = Database.Documents.Get(PeriodicExportSetup.RavenDocumentKey, null);
                    if (document == null)
                    {
                        exportConfigs = null;
                        exportStatus  = null;
                        return;
                    }

                    var status = Database.Documents.Get(PeriodicExportStatus.RavenDocumentKey, null);

                    exportStatus  = status == null ? new PeriodicExportStatus() : status.DataAsJson.JsonDeserialization <PeriodicExportStatus>();
                    exportConfigs = document.DataAsJson.JsonDeserialization <PeriodicExportSetup>();


                    awsAccessKey        = Database.Configuration.Settings["Raven/AWSAccessKey"];
                    awsSecretKey        = Database.Configuration.Settings["Raven/AWSSecretKey"];
                    azureStorageAccount = Database.Configuration.Settings["Raven/AzureStorageAccount"];
                    azureStorageKey     = Database.Configuration.Settings["Raven/AzureStorageKey"];

                    if (exportConfigs.IntervalMilliseconds > 0)
                    {
                        var interval = TimeSpan.FromMilliseconds(exportConfigs.IntervalMilliseconds);
                        logger.Info("Incremental periodic export started, will export every" + interval.TotalMinutes + "minutes");

                        var timeSinceLastBackup = SystemTime.UtcNow - exportStatus.LastBackup;
                        var nextBackup          = timeSinceLastBackup >= interval ? TimeSpan.Zero : interval - timeSinceLastBackup;
                        incrementalBackupTimer = new Timer(state => TimerCallback(false), null, nextBackup, interval);
                    }
                    else
                    {
                        logger.Warn("Incremental periodic export interval is set to zero or less, incremental periodic export is now disabled");
                    }

                    if (exportConfigs.FullBackupIntervalMilliseconds > 0)
                    {
                        var interval = TimeSpan.FromMilliseconds(exportConfigs.FullBackupIntervalMilliseconds);
                        logger.Info("Full periodic export started, will export every" + interval.TotalMinutes + "minutes");

                        var timeSinceLastBackup = SystemTime.UtcNow - exportStatus.LastFullBackup;
                        var nextBackup          = timeSinceLastBackup >= interval ? TimeSpan.Zero : interval - timeSinceLastBackup;
                        fullBackupTimer = new Timer(state => TimerCallback(true), null, nextBackup, interval);
                    }
                    else
                    {
                        logger.Warn("Full periodic export interval is set to zero or less, full periodic export is now disabled");
                    }
                }
                catch (Exception ex)
                {
                    logger.ErrorException("Could not read periodic export config", ex);
                    Database.AddAlert(new Alert
                    {
                        AlertLevel = AlertLevel.Error,
                        CreatedAt  = SystemTime.UtcNow,
                        Message    = ex.Message,
                        Title      = "Could not read periodic export config",
                        Exception  = ex.ToString(),
                        UniqueKey  = "Periodic Export Config Error"
                    });
                }
            }
        }
Ejemplo n.º 10
0
        private void ReadSetupValuesFromDocument()
        {
            using (LogContext.WithResource(Database.Name))
            {
                try
                {
                    // Not having a setup doc means this DB isn't enabled for periodic exports
                    var configurationDocument = Database.ConfigurationRetriever.GetConfigurationDocument <PeriodicExportSetup>(PeriodicExportSetup.RavenDocumentKey);
                    if (configurationDocument == null)
                    {
                        exportConfigs = null;
                        exportStatus  = null;
                        return;
                    }

                    exportStatus  = GetExportStatus();
                    exportConfigs = configurationDocument.MergedDocument;

                    if (exportConfigs.Disabled)
                    {
                        logger.Info("Periodic export is disabled.");
                        return;
                    }

                    awsAccessKey        = Database.ConfigurationRetriever.GetEffectiveConfigurationSetting(Constants.PeriodicExport.AwsAccessKey);
                    awsSecretKey        = Database.ConfigurationRetriever.GetEffectiveConfigurationSetting(Constants.PeriodicExport.AwsSecretKey);
                    azureStorageAccount = Database.ConfigurationRetriever.GetEffectiveConfigurationSetting(Constants.PeriodicExport.AzureStorageAccount);
                    azureStorageKey     = Database.ConfigurationRetriever.GetEffectiveConfigurationSetting(Constants.PeriodicExport.AzureStorageKey);

                    if (exportConfigs.IntervalMilliseconds.GetValueOrDefault() > 0)
                    {
                        IncrementalInterval             = TimeSpan.FromMilliseconds(exportConfigs.IntervalMilliseconds.GetValueOrDefault());
                        incrementalIntermediateInterval = TimeSpan.FromMilliseconds(IncrementalInterval.TotalMilliseconds);

                        logger.Info("Incremental periodic export started, will export every" + IncrementalInterval.TotalMinutes + "minutes");

                        if (IsValidTimespanForTimer(IncrementalInterval))
                        {
                            var timeSinceLastBackup = SystemTime.UtcNow - exportStatus.LastBackup;
                            var nextBackup          = timeSinceLastBackup >= IncrementalInterval ? TimeSpan.Zero : IncrementalInterval - timeSinceLastBackup;

                            incrementalBackupTimer = Database.TimerManager.NewTimer(state => TimerCallback(false), nextBackup, IncrementalInterval);
                        }
                        else
                        {
                            incrementalBackupTimer = Database.TimerManager.NewTimer(state => LongPeriodTimerCallback(false),
                                                                                    TimeSpan.FromMilliseconds(maxTimerTimeoutInMilliseconds), Timeout.InfiniteTimeSpan);
                        }
                    }
                    else
                    {
                        logger.Warn("Incremental periodic export interval is set to zero or less, incremental periodic export is now disabled");
                    }

                    if (exportConfigs.FullBackupIntervalMilliseconds.GetValueOrDefault() > 0)
                    {
                        FullBackupInterval             = TimeSpan.FromMilliseconds(exportConfigs.FullBackupIntervalMilliseconds.GetValueOrDefault());
                        fullBackupIntermediateInterval = TimeSpan.FromMilliseconds(FullBackupInterval.TotalMilliseconds);

                        logger.Info("Full periodic export started, will export every" + FullBackupInterval.TotalMinutes + "minutes");

                        if (IsValidTimespanForTimer(FullBackupInterval))
                        {
                            var timeSinceLastBackup = SystemTime.UtcNow - exportStatus.LastFullBackup;
                            var nextBackup          = timeSinceLastBackup >= FullBackupInterval ? TimeSpan.Zero : FullBackupInterval - timeSinceLastBackup;

                            fullBackupTimer = Database.TimerManager.NewTimer(state => TimerCallback(true), nextBackup, FullBackupInterval);
                        }
                        else
                        {
                            fullBackupTimer = Database.TimerManager.NewTimer(state => LongPeriodTimerCallback(true),
                                                                             TimeSpan.FromMilliseconds(maxTimerTimeoutInMilliseconds), Timeout.InfiniteTimeSpan);
                        }
                    }
                    else
                    {
                        logger.Warn("Full periodic export interval is set to zero or less, full periodic export is now disabled");
                    }
                }
                catch (Exception ex)
                {
                    logger.ErrorException("Could not read periodic export config", ex);
                    Database.AddAlert(new Alert
                    {
                        AlertLevel = AlertLevel.Error,
                        CreatedAt  = SystemTime.UtcNow,
                        Message    = ex.Message,
                        Title      = "Could not read periodic export config",
                        Exception  = ex.ToString(),
                        UniqueKey  = "Periodic Export Config Error"
                    });
                }
            }
        }
Ejemplo n.º 11
0
        public void CanBackupToDirectory_MultipleBackups()
        {
            var backupPath = NewDataPath("BackupFolder");

            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "oren"
                    });
                    var periodicBackupSetup = new PeriodicExportSetup
                    {
                        LocalFolderName      = backupPath,
                        IntervalMilliseconds = 25
                    };
                    session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                    session.SaveChanges();
                }
                SpinWait.SpinUntil(() =>
                {
                    var jsonDocument = store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey);
                    if (jsonDocument == null)
                    {
                        return(false);
                    }
                    var periodicBackupStatus = jsonDocument.DataAsJson.JsonDeserialization <PeriodicExportStatus>();
                    return(periodicBackupStatus.LastDocsEtag != Etag.Empty && periodicBackupStatus.LastDocsEtag != null);
                });

                var etagForBackups = store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey).Etag;
                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "ayende"
                    });
                    session.SaveChanges();
                }
                SpinWait.SpinUntil(() =>
                                   store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey).Etag != etagForBackups);
            }

            using (var store = NewDocumentStore())
            {
                var dataDumper = new DatabaseDataDumper(store.SystemDatabase)
                {
                    Options = { Incremental = true }
                };
                dataDumper.ImportData(new SmugglerImportOptions <RavenConnectionStringOptions> {
                    FromFile = backupPath
                }).Wait();

                using (var session = store.OpenSession())
                {
                    Assert.Equal("oren", session.Load <User>(1).Name);
                    Assert.Equal("ayende", session.Load <User>(2).Name);
                }
            }
            IOExtensions.DeleteDirectory(backupPath);
        }
Ejemplo n.º 12
0
        public void PeriodicBackupDoesntProduceExcessiveFilesAndCleanupTombstonesProperly()
        {
            var backupPath = NewDataPath("BackupFolder");

            using (var store = NewDocumentStore())
            {
                using (var session = store.OpenSession())
                {
                    var periodicBackupSetup = new PeriodicExportSetup
                    {
                        LocalFolderName      = backupPath,
                        IntervalMilliseconds = 250
                    };
                    session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                    session.SaveChanges();
                }

                var backupStatus = GetPerodicBackupStatus(store.SystemDatabase);

                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "oren"
                    });
                    session.Store(new User {
                        Name = "ayende"
                    });
                    store.DatabaseCommands.PutAttachment("attach/1", null, new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }), new RavenJObject());
                    store.DatabaseCommands.PutAttachment("attach/2", null, new MemoryStream(new byte[] { 1, 2, 3, 4, 5 }), new RavenJObject());
                    session.SaveChanges();
                }

                WaitForPeriodicExport(store.SystemDatabase, backupStatus);

                // status + one export
                VerifyFilesCount(1 + 1, backupPath);

                store.DatabaseCommands.Delete("users/1", null);
                store.DatabaseCommands.Delete("users/2", null);
                store.DatabaseCommands.DeleteAttachment("attach/1", null);
                store.DatabaseCommands.DeleteAttachment("attach/2", null);

                store.SystemDatabase.TransactionalStorage.Batch(accessor =>
                {
                    Assert.Equal(2,
                                 accessor.Lists.Read(Constants.RavenPeriodicExportsDocsTombstones, Etag.Empty, null, 20)
                                 .Count());
                    Assert.Equal(2,
                                 accessor.Lists.Read(Constants.RavenPeriodicExportsAttachmentsTombstones, Etag.Empty, null, 20)
                                 .Count());
                });


                WaitForPeriodicExport(store.SystemDatabase, backupStatus);

                // status + two exports
                VerifyFilesCount(1 + 2, backupPath);

                store.SystemDatabase.TransactionalStorage.Batch(accessor =>
                {
                    Assert.Equal(1,
                                 accessor.Lists.Read(Constants.RavenPeriodicExportsDocsTombstones, Etag.Empty, null, 20)
                                 .Count());
                    Assert.Equal(1,
                                 accessor.Lists.Read(Constants.RavenPeriodicExportsAttachmentsTombstones, Etag.Empty, null, 20)
                                 .Count());
                });
            }

            IOExtensions.DeleteDirectory(backupPath);
        }
Ejemplo n.º 13
0
        public void SmugglerCanUnderstandPeriodicBackupFormat()
        {
            var backupPath = NewDataPath("BackupFolder");

            using (var store = NewDocumentStore())
            {
                string userId;
                using (var session = store.OpenSession())
                {
                    var periodicBackupSetup = new PeriodicExportSetup
                    {
                        LocalFolderName      = backupPath,
                        IntervalMilliseconds = 100
                    };
                    session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                    session.SaveChanges();
                }

                var backupStatus = GetPerodicBackupStatus(store.SystemDatabase);

                using (var session = store.OpenSession())
                {
                    var user = new User {
                        Name = "oren"
                    };
                    session.Store(user);
                    userId = user.Id;
                    session.SaveChanges();
                }
                store.DatabaseCommands.PutAttachment("attach/1", null, new MemoryStream(new byte[] { 1, 2, 3, 4 }), new RavenJObject());

                WaitForPeriodicExport(store.SystemDatabase, backupStatus);

                store.DatabaseCommands.Delete(userId, null);
                store.DatabaseCommands.DeleteAttachment("attach/1", null);

                WaitForPeriodicExport(store.SystemDatabase, backupStatus);
            }

            using (var store = NewRemoteDocumentStore())
            {
                var dataDumper = new SmugglerApi();
                dataDumper.SmugglerOptions.Incremental = true;
                dataDumper.ImportData(
                    new SmugglerImportOptions
                {
                    FromFile = backupPath,
                    To       = new RavenConnectionStringOptions {
                        Url = store.Url
                    }
                }).Wait();

                using (var session = store.OpenSession())
                {
                    Assert.Null(session.Load <User>(1));
                    Assert.Null(store.DatabaseCommands.GetAttachment("attach/1"));
                }
            }

            IOExtensions.DeleteDirectory(backupPath);
        }
Ejemplo n.º 14
0
        public void CanBackupToDirectory_MultipleBackups_with_long_interval()
        {
            var backupPath = NewDataPath("BackupFolder");

            using (var store = NewDocumentStore())
            {
                var periodicExportTask = store.DocumentDatabase.StartupTasks.OfType <PeriodicExportTask>().FirstOrDefault();

                //get by reflection the maxTimerTimeoutInMilliseconds field
                //this field is the maximum interval acceptable in .Net's threading timer
                //if the requested export interval is bigger than this maximum interval,
                //a timer with maximum interval will be used several times until the interval cumulatively
                //will be equal to requested interval
                var maxTimerTimeoutInMillisecondsField = typeof(PeriodicExportTask)
                                                         .GetField("maxTimerTimeoutInMilliseconds",
                                                                   BindingFlags.Instance | BindingFlags.NonPublic);

                Assert.NotNull(maxTimerTimeoutInMillisecondsField); //sanity check, can fail here only in case of source code change
                //that removes this field
                maxTimerTimeoutInMillisecondsField.SetValue(periodicExportTask, 5);

                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "oren"
                    });
                    var periodicBackupSetup = new PeriodicExportSetup
                    {
                        LocalFolderName      = backupPath,
                        IntervalMilliseconds = 25
                    };
                    session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);

                    session.SaveChanges();
                }
                SpinWait.SpinUntil(() =>
                {
                    var jsonDocument = store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey);
                    if (jsonDocument == null)
                    {
                        return(false);
                    }
                    var periodicBackupStatus = jsonDocument.DataAsJson.JsonDeserialization <PeriodicExportStatus>();
                    return(periodicBackupStatus.LastDocsEtag != Etag.Empty && periodicBackupStatus.LastDocsEtag != null);
                });

                var etagForBackups = store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey).Etag;
                using (var session = store.OpenSession())
                {
                    session.Store(new User {
                        Name = "ayende"
                    });
                    session.SaveChanges();
                }
                SpinWait.SpinUntil(() =>
                                   store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey).Etag != etagForBackups);
            }

            using (var store = NewDocumentStore())
            {
                var dataDumper = new DatabaseDataDumper(store.SystemDatabase)
                {
                    Options = { Incremental = true }
                };
                dataDumper.ImportData(new SmugglerImportOptions <RavenConnectionStringOptions> {
                    FromFile = backupPath
                }).Wait();

                using (var session = store.OpenSession())
                {
                    Assert.Equal("oren", session.Load <User>(1).Name);
                    Assert.Equal("ayende", session.Load <User>(2).Name);
                }
            }
            IOExtensions.DeleteDirectory(backupPath);
        }
Ejemplo n.º 15
0
        public void PeriodicExport_should_work_with_long_intervals()
        {
            var backupPath = NewDataPath("BackupFolder");

            try
            {
                using (var store = NewDocumentStore())
                {
                    var periodicExportTask = store.DocumentDatabase.StartupTasks.OfType <PeriodicExportTask>().FirstOrDefault();

                    //get by reflection the maxTimerTimeoutInMilliseconds field
                    //this field is the maximum interval acceptable in .Net's threading timer
                    //if the requested export interval is bigger than this maximum interval,
                    //a timer with maximum interval will be used several times until the interval cumulatively
                    //will be equal to requested interval
                    var maxTimerTimeoutInMillisecondsField = typeof(PeriodicExportTask)
                                                             .GetField("maxTimerTimeoutInMilliseconds",
                                                                       BindingFlags.Instance | BindingFlags.NonPublic);

                    Assert.NotNull(maxTimerTimeoutInMillisecondsField); //sanity check, can fail here only in case of source code change
                    //that removes this field
                    maxTimerTimeoutInMillisecondsField.SetValue(periodicExportTask, 5);

                    using (var session = store.OpenSession())
                    {
                        session.Store(new User {
                            Name = "oren"
                        });
                        var periodicBackupSetup = new PeriodicExportSetup
                        {
                            LocalFolderName      = backupPath,
                            IntervalMilliseconds = 25
                        };
                        session.Store(periodicBackupSetup, PeriodicExportSetup.RavenDocumentKey);
                        session.SaveChanges();
                    }
                    SpinWait.SpinUntil(() => store.DatabaseCommands.Get(PeriodicExportStatus.RavenDocumentKey) != null, 10000);
                }

                using (var store = NewDocumentStore())
                {
                    var actualBackupPath   = Directory.GetDirectories(backupPath)[0];
                    var fullBackupFilePath = Directory.GetFiles(actualBackupPath).FirstOrDefault(x => x.Contains("full"));
                    Assert.NotNull(fullBackupFilePath);

                    // import the full backup
                    var dataDumper = new DatabaseDataDumper(store.SystemDatabase);
                    dataDumper.ImportData(new SmugglerImportOptions <RavenConnectionStringOptions> {
                        FromFile = fullBackupFilePath
                    }).Wait();

                    using (var session = store.OpenSession())
                    {
                        Assert.Equal("oren", session.Load <User>(1).Name);
                    }
                }
            }
            finally
            {
                IOExtensions.DeleteDirectory(backupPath);
            }
        }