public void restore_google_cloud_settings_tests() { using (var store = GetDocumentStore(new Options { ModifyDatabaseName = s => $"{s}_2" })) { var databaseName = $"restored_database-{Guid.NewGuid()}"; var restoreConfiguration = new RestoreFromGoogleCloudConfiguration { DatabaseName = databaseName }; var restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); var e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Google Cloud Bucket name cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.BucketName = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Google Credentials JSON cannot be null or empty", e.InnerException.Message); restoreConfiguration.Settings.GoogleCredentialsJson = "test"; restoreBackupTask = new RestoreBackupOperation(restoreConfiguration); e = Assert.Throws <RavenException>(() => store.Maintenance.Server.Send(restoreBackupTask)); Assert.Contains("Wrong format for Google Credentials.", e.InnerException.Message); } }
public async Task can_backup_and_restore() { using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); session.CountersFor("users/1").Increment("likes", 100); await session.SaveChangesAsync(); } var googleCloudSettings = GetGoogleCloudSettings(); var config = Backup.CreateBackupConfiguration(googleCloudSettings: googleCloudSettings); var backupTaskId = Backup.UpdateConfigAndRunBackup(Server, config, store); var backupResult = (BackupResult)store.Maintenance.Send(new GetOperationStateOperation(Backup.GetBackupOperationId(store, backupTaskId))).Result; Assert.NotNull(backupResult); Assert.True(backupResult.Counters.Processed); Assert.Equal(1, backupResult.Counters.ReadCount); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); session.CountersFor("users/2").Increment("downloads", 200); await session.SaveChangesAsync(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; var status = Backup.RunBackupAndReturnStatus(Server, backupTaskId, store, isFullBackup: false, expectedEtag: lastEtag); // restore the database with a different name var databaseName = $"restored_database-{Guid.NewGuid()}"; var subfolderGoogleCloudSettings = GetGoogleCloudSettings(status.FolderName); var restoreFromGoogleCloudConfiguration = new RestoreFromGoogleCloudConfiguration { DatabaseName = databaseName, Settings = subfolderGoogleCloudSettings, DisableOngoingTasks = true }; using (Backup.RestoreDatabaseFromCloud(store, restoreFromGoogleCloudConfiguration, TimeSpan.FromSeconds(30))) { using (var session = store.OpenAsyncSession(databaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = await session.CountersFor("users/1").GetAsync("likes"); Assert.Equal(100, val); val = await session.CountersFor("users/2").GetAsync("downloads"); Assert.Equal(200, val); } var originalDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var restoredDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName); using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Contains($"A:7-{originalDatabase.DbBase64Id}", databaseChangeVector); Assert.Contains($"A:8-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }
public async Task can_backup_and_restore_snapshot() { using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); await session.SaveChangesAsync(); } using (var session = store.OpenAsyncSession()) { await session .Query <User>() .Where(x => x.Name == "oren") .ToListAsync(); // create an index to backup await session .Query <Order>() .Where(x => x.Freight > 20) .ToListAsync(); // create an index to backup session.CountersFor("users/1").Increment("likes", 100); //create a counter to backup await session.SaveChangesAsync(); } var googleCloudSettings = GetGoogleCloudSettings(); var config = Backup.CreateBackupConfiguration(backupType: BackupType.Snapshot, googleCloudSettings: googleCloudSettings); var backupTaskId = Backup.UpdateConfigAndRunBackup(Server, config, store); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); await session.StoreAsync(new User { Name = "ayende" }, "users/3"); session.CountersFor("users/2").Increment("downloads", 200); await session.SaveChangesAsync(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; var status = Backup.RunBackupAndReturnStatus(Server, backupTaskId, store, isFullBackup: false, expectedEtag: lastEtag); // restore the database with a different name string databaseName = $"restored_database_snapshot-{Guid.NewGuid()}"; var subfolderGoogleCloudSettings = GetGoogleCloudSettings(status.FolderName); var restoreFromGoogleCloudConfiguration = new RestoreFromGoogleCloudConfiguration { DatabaseName = databaseName, Settings = subfolderGoogleCloudSettings }; using (Backup.RestoreDatabaseFromCloud(store, restoreFromGoogleCloudConfiguration, TimeSpan.FromSeconds(300))) { using (var session = store.OpenAsyncSession(databaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.NotNull(users["users/1"]); Assert.NotNull(users["users/2"]); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = await session.CountersFor("users/1").GetAsync("likes"); Assert.Equal(100, val); val = await session.CountersFor("users/2").GetAsync("downloads"); Assert.Equal(200, val); } var stats = await store.Maintenance.SendAsync(new GetStatisticsOperation()); Assert.Equal(2, stats.CountOfIndexes); var originalDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var restoredDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName); using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Contains($"A:8-{originalDatabase.DbBase64Id}", databaseChangeVector); Assert.Contains($"A:10-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }
public RestoreFromGoogleCloud(ServerStore serverStore, RestoreFromGoogleCloudConfiguration restoreFromConfiguration, string nodeTag, OperationCancelToken operationCancelToken) : base(serverStore, restoreFromConfiguration, nodeTag, operationCancelToken) { _client = new RavenGoogleCloudClient(restoreFromConfiguration.Settings, serverStore.Configuration.Backup); _remoteFolderName = restoreFromConfiguration.Settings.RemoteFolderName; }
public async Task can_backup_and_restore() { using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); session.CountersFor("users/1").Increment("likes", 100); await session.SaveChangesAsync(); } var config = new PeriodicBackupConfiguration { BackupType = BackupType.Backup, GoogleCloudSettings = GoogleCloudFact.GoogleCloudSettings, IncrementalBackupFrequency = "* * * * *" //every minute }; var backupTaskId = (await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config))).TaskId; await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); var value = WaitForValue(() => { var status = store.Maintenance.Send(operation).Status; return(status?.LastEtag); }, 4); Assert.Equal(4, value); var backupStatus = store.Maintenance.Send(operation); var backupOperationId = backupStatus.Status.LastOperationId; var backupOperation = store.Maintenance.Send(new GetOperationStateOperation(backupOperationId.Value)); var backupResult = backupOperation.Result as BackupResult; Assert.True(backupResult.Counters.Processed); Assert.Equal(1, backupResult.Counters.ReadCount); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); session.CountersFor("users/2").Increment("downloads", 200); await session.SaveChangesAsync(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; await store.Maintenance.SendAsync(new StartBackupOperation(false, backupTaskId)); value = WaitForValue(() => store.Maintenance.Send(operation).Status.LastEtag, lastEtag); Assert.Equal(lastEtag, value); // restore the database with a different name var databaseName = $"restored_database-{Guid.NewGuid()}"; GoogleCloudFact.GoogleCloudSettings.RemoteFolderName = $"{backupStatus.Status.FolderName}"; var restoreFromGoogleCloudConfiguration = new RestoreFromGoogleCloudConfiguration() { DatabaseName = databaseName, Settings = GoogleCloudFact.GoogleCloudSettings }; var googleCloudOperation = new RestoreBackupOperation(restoreFromGoogleCloudConfiguration); var restoreOperation = store.Maintenance.Server.Send(googleCloudOperation); restoreOperation.WaitForCompletion(TimeSpan.FromSeconds(30)); { using (var session = store.OpenAsyncSession(databaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = await session.CountersFor("users/1").GetAsync("likes"); Assert.Equal(100, val); val = await session.CountersFor("users/2").GetAsync("downloads"); Assert.Equal(200, val); } var originalDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var restoredDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName); using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Equal($"A:7-{originalDatabase.DbBase64Id}, A:8-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }
public async Task can_backup_and_restore_snapshot() { using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); await session.SaveChangesAsync(); } using (var session = store.OpenAsyncSession()) { await session .Query <User>() .Where(x => x.Name == "oren") .ToListAsync(); // create an index to backup await session .Query <Order>() .Where(x => x.Freight > 20) .ToListAsync(); // create an index to backup session.CountersFor("users/1").Increment("likes", 100); //create a counter to backup await session.SaveChangesAsync(); } var googleCloudSettings = GetGoogleCloudSettings(); var config = new PeriodicBackupConfiguration { BackupType = BackupType.Snapshot, GoogleCloudSettings = googleCloudSettings, IncrementalBackupFrequency = "* * * * *" //every minute }; var backupTaskId = (await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config))).TaskId; await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); var value = WaitForValue(() => { var status = store.Maintenance.Send(operation).Status; return(status?.LastEtag); }, 4); Assert.Equal(4, value); var backupStatus = store.Maintenance.Send(operation); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); await session.StoreAsync(new User { Name = "ayende" }, "users/3"); session.CountersFor("users/2").Increment("downloads", 200); await session.SaveChangesAsync(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; await store.Maintenance.SendAsync(new StartBackupOperation(false, backupTaskId)); value = WaitForValue(() => store.Maintenance.Send(operation).Status.LastEtag, lastEtag); Assert.Equal(lastEtag, value); // restore the database with a different name string databaseName = $"restored_database_snapshot-{Guid.NewGuid()}"; var subfolderGoogleCloudSettings = GetGoogleCloudSettings(backupStatus.Status.FolderName); var restoreFromGoogleCloudConfiguration = new RestoreFromGoogleCloudConfiguration { DatabaseName = databaseName, Settings = subfolderGoogleCloudSettings }; using (RestoreDatabaseFromCloud(store, restoreFromGoogleCloudConfiguration, TimeSpan.FromSeconds(300))) { using (var session = store.OpenAsyncSession(databaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.NotNull(users["users/1"]); Assert.NotNull(users["users/2"]); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = await session.CountersFor("users/1").GetAsync("likes"); Assert.Equal(100, val); val = await session.CountersFor("users/2").GetAsync("downloads"); Assert.Equal(200, val); } var stats = await store.Maintenance.SendAsync(new GetStatisticsOperation()); Assert.Equal(2, stats.CountOfIndexes); var originalDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var restoredDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName); using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Equal($"A:8-{originalDatabase.DbBase64Id}, A:10-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }
public async Task can_backup_and_restore() { using (var store = GetDocumentStore()) { using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "oren" }, "users/1"); session.CountersFor("users/1").Increment("likes", 100); await session.SaveChangesAsync(); } var googleCloudSettings = GetGoogleCloudSettings(); var config = new PeriodicBackupConfiguration { BackupType = BackupType.Backup, GoogleCloudSettings = googleCloudSettings, IncrementalBackupFrequency = "0 0 1 1 *" }; var backupTaskId = (await store.Maintenance.SendAsync(new UpdatePeriodicBackupOperation(config))).TaskId; await store.Maintenance.SendAsync(new StartBackupOperation(true, backupTaskId)); var operation = new GetPeriodicBackupStatusOperation(backupTaskId); PeriodicBackupStatus status = null; var value = WaitForValue(() => { status = store.Maintenance.Send(operation).Status; return(status?.LastEtag); }, 4); Assert.True(4 == value, $"4 == value, Got status: {status != null}, exception: {status?.Error?.Exception}"); Assert.True(status.LastOperationId != null, $"status.LastOperationId != null, Got status: {status != null}, exception: {status?.Error?.Exception}"); OperationState backupOperation = null; var operationStatus = WaitForValue(() => { backupOperation = store.Maintenance.Send(new GetOperationStateOperation(status.LastOperationId.Value)); return(backupOperation.Status); }, OperationStatus.Completed); Assert.Equal(OperationStatus.Completed, operationStatus); var backupResult = backupOperation.Result as BackupResult; Assert.NotNull(backupResult); Assert.True(backupResult.Counters.Processed); Assert.Equal(1, backupResult.Counters.ReadCount); using (var session = store.OpenAsyncSession()) { await session.StoreAsync(new User { Name = "ayende" }, "users/2"); session.CountersFor("users/2").Increment("downloads", 200); await session.SaveChangesAsync(); } var lastEtag = store.Maintenance.Send(new GetStatisticsOperation()).LastDocEtag; await store.Maintenance.SendAsync(new StartBackupOperation(false, backupTaskId)); value = WaitForValue(() => store.Maintenance.Send(operation).Status.LastEtag, lastEtag); Assert.Equal(lastEtag, value); // restore the database with a different name var databaseName = $"restored_database-{Guid.NewGuid()}"; var subfolderGoogleCloudSettings = GetGoogleCloudSettings(status.FolderName); var restoreFromGoogleCloudConfiguration = new RestoreFromGoogleCloudConfiguration { DatabaseName = databaseName, Settings = subfolderGoogleCloudSettings, DisableOngoingTasks = true }; using (RestoreDatabaseFromCloud(store, restoreFromGoogleCloudConfiguration, TimeSpan.FromSeconds(30))) { using (var session = store.OpenAsyncSession(databaseName)) { var users = await session.LoadAsync <User>(new[] { "users/1", "users/2" }); Assert.True(users.Any(x => x.Value.Name == "oren")); Assert.True(users.Any(x => x.Value.Name == "ayende")); var val = await session.CountersFor("users/1").GetAsync("likes"); Assert.Equal(100, val); val = await session.CountersFor("users/2").GetAsync("downloads"); Assert.Equal(200, val); } var originalDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store.Database); var restoredDatabase = await Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(databaseName); using (restoredDatabase.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext ctx)) using (ctx.OpenReadTransaction()) { var databaseChangeVector = DocumentsStorage.GetDatabaseChangeVector(ctx); Assert.Contains($"A:7-{originalDatabase.DbBase64Id}", databaseChangeVector); Assert.Contains($"A:8-{restoredDatabase.DbBase64Id}", databaseChangeVector); } } } }