public BackupProgress StartRestore(StartRestoreRequest request) { if (request.StorageType == BackupStorageType.Local) { if (string.IsNullOrEmpty(request.FilePathOrId) || !File.Exists(request.FilePathOrId)) { throw new FileNotFoundException(); } } if (!request.BackupId.Equals(Guid.Empty)) { var backupRepository = BackupStorageFactory.GetBackupRepository(); var backupRecord = backupRepository.GetBackupRecord(request.BackupId); if (backupRecord == null) { throw new FileNotFoundException(); } request.FilePathOrId = backupRecord.StoragePath; request.StorageType = backupRecord.StorageType; request.StorageParams = backupRecord.StorageParams; } var progress = BackupWorker.StartRestore(request); if (!string.IsNullOrEmpty(progress.Error)) { throw new FaultException(progress.Error); } return(progress); }
public List <BackupHistoryRecord> GetBackupHistory(int tenantId) { var backupHistory = new List <BackupHistoryRecord>(); var backupRepository = BackupStorageFactory.GetBackupRepository(); foreach (var record in backupRepository.GetBackupRecordsByTenantId(tenantId)) { var storage = BackupStorageFactory.GetBackupStorage(record.StorageType, record.TenantId); if (storage.IsExists(record.StoragePath)) { backupHistory.Add(new BackupHistoryRecord { Id = record.Id, FileName = record.FileName, StorageType = record.StorageType, CreatedOn = record.CreatedOn, ExpiresOn = record.ExpiresOn }); } else { backupRepository.DeleteBackupRecord(record.Id); } } return(backupHistory); }
public BackupCleanerHelperService( IOptionsMonitor <ILog> options, BackupRepository backupRepository, BackupStorageFactory backupStorageFactory) { log = options.CurrentValue; BackupRepository = backupRepository; BackupStorageFactory = backupStorageFactory; }
private void ScheduleBackupTasks() { if (Monitor.TryEnter(schedulerLock)) { try { log.DebugFormat("started to schedule backups"); var backupRepostory = BackupStorageFactory.GetBackupRepository(); var backupsToSchedule = backupRepostory.GetBackupSchedules().Where(schedule => schedule.IsToBeProcessed()).ToList(); log.DebugFormat("{0} backups are to schedule", backupsToSchedule.Count); foreach (var schedule in backupsToSchedule) { if (!isStarted) { return; } try { if (CoreContext.Configuration.Standalone || CoreContext.TenantManager.GetTenantQuota(schedule.TenantId).AutoBackup) { var tariff = CoreContext.PaymentManager.GetTariff(schedule.TenantId); if (tariff.State < TariffState.Delay) { schedule.LastBackupTime = DateTime.UtcNow; backupRepostory.SaveBackupSchedule(schedule); log.DebugFormat("Start scheduled backup: {0}, {1}, {2}, {3}", schedule.TenantId, schedule.BackupMail, schedule.StorageType, schedule.StorageBasePath); BackupWorker.StartScheduledBackup(schedule); } else { log.DebugFormat("Skip portal {0} not paid", schedule.TenantId); } } else { log.DebugFormat("Skip portal {0} haven't access", schedule.TenantId); } } catch (Exception error) { log.Error("error while scheduling backups: {0}", error); } } } catch (Exception error) { log.Error("error while scheduling backups: {0}", error); } finally { Monitor.Exit(schedulerLock); } } }
public void DeleteBackup(Guid id) { var backupRepository = BackupStorageFactory.GetBackupRepository(); var backupRecord = backupRepository.GetBackupRecord(id); backupRepository.DeleteBackupRecord(backupRecord.Id); var storage = BackupStorageFactory.GetBackupStorage(backupRecord.StorageType, backupRecord.TenantId); storage.Delete(backupRecord.StoragePath); }
public void CreateSchedule(CreateScheduleRequest request) { BackupStorageFactory.GetBackupRepository().SaveBackupSchedule( new Schedule(request.TenantId) { Cron = request.Cron, BackupMail = request.BackupMail, NumberOfBackupsStored = request.NumberOfBackupsStored, StorageType = request.StorageType, StorageBasePath = request.StorageBasePath }); }
public BackupService( IOptionsMonitor <ILog> options, BackupStorageFactory backupStorageFactory, BackupWorker backupWorker, BackupRepository backupRepository, ConfigurationExtension configuration) { Log = options.CurrentValue; BackupStorageFactory = backupStorageFactory; BackupWorker = backupWorker; BackupRepository = backupRepository; Configuration = configuration; }
public void DeleteBackup(Guid id) { var backupRecord = BackupRepository.GetBackupRecord(id); BackupRepository.DeleteBackupRecord(backupRecord.Id); var storage = BackupStorageFactory.GetBackupStorage(backupRecord); if (storage == null) { return; } storage.Delete(backupRecord.StoragePath); }
public ScheduleResponse GetSchedule(int tenantId) { var schedule = BackupStorageFactory.GetBackupRepository().GetBackupSchedule(tenantId); return(schedule != null ? new ScheduleResponse { StorageType = schedule.StorageType, StorageBasePath = schedule.StorageBasePath, BackupMail = schedule.BackupMail, NumberOfBackupsStored = schedule.NumberOfBackupsStored, Cron = schedule.Cron, LastBackupTime = schedule.LastBackupTime } : null); }
public void DeleteAllBackups(int tenantId) { var backupRepository = BackupStorageFactory.GetBackupRepository(); foreach (var backupRecord in backupRepository.GetBackupRecordsByTenantId(tenantId)) { try { backupRepository.DeleteBackupRecord(backupRecord.Id); var storage = BackupStorageFactory.GetBackupStorage(backupRecord.StorageType, backupRecord.TenantId); storage.Delete(backupRecord.StoragePath); } catch (Exception error) { log.Warn("error while removing backup record: {0}", error); } } }
public void DeleteAllBackups(int tenantId) { foreach (var backupRecord in BackupRepository.GetBackupRecordsByTenantId(tenantId)) { try { BackupRepository.DeleteBackupRecord(backupRecord.Id); var storage = BackupStorageFactory.GetBackupStorage(backupRecord); if (storage == null) { continue; } storage.Delete(backupRecord.StoragePath); } catch (Exception error) { Log.Warn("error while removing backup record: {0}", error); } } }
public BackupProgress StartRestore(StartRestoreRequest request) { if (!request.BackupId.Equals(Guid.Empty)) { var backupRepository = BackupStorageFactory.GetBackupRepository(); var backupRecord = backupRepository.GetBackupRecord(request.BackupId); if (backupRecord == null) { throw new FileNotFoundException(); } request.FilePathOrId = backupRecord.StoragePath; request.StorageType = backupRecord.StorageType; } var progress = BackupWorker.StartRestore(request.TenantId, request.StorageType, request.FilePathOrId, request.NotifyAfterCompletion); if (!string.IsNullOrEmpty(progress.Error)) { throw new FaultException(progress.Error); } return(progress); }
public void DeleteSchedule(int tenantId) { BackupStorageFactory.GetBackupRepository().DeleteBackupSchedule(tenantId); }
public void RunJob() { Tenant tenant = null; var tempFile = PathHelper.GetTempFileName(TempFolder); try { NotifyHelper.SendAboutRestoreStarted(TenantId, Notify); var storage = BackupStorageFactory.GetBackupStorage(StorageType, TenantId, StorageParams); storage.Download(StoragePath, tempFile); if (!CoreContext.Configuration.Standalone) { var backupHash = GetBackupHash(tempFile); var repo = BackupStorageFactory.GetBackupRepository(); var record = repo.GetBackupRecord(backupHash, TenantId); if (record == null) { throw new Exception(BackupResource.BackupNotFound); } } Percentage = 10; tenant = CoreContext.TenantManager.GetTenant(TenantId); tenant.SetStatus(TenantStatus.Restoring); CoreContext.TenantManager.SaveTenant(tenant); var columnMapper = new ColumnMapper(); columnMapper.SetMapping("tenants_tenants", "alias", tenant.TenantAlias, ((Guid)Id).ToString("N")); columnMapper.Commit(); var restoreTask = new RestorePortalTask(Log, TenantId, configPaths[currentRegion], tempFile, columnMapper, upgradesPath); restoreTask.ProgressChanged += (sender, args) => Percentage = (10d + 0.65 * args.Progress); restoreTask.RunJob(); Tenant restoredTenant = null; if (restoreTask.Dump) { AscCache.OnClearCache(); if (Notify) { var tenants = CoreContext.TenantManager.GetTenants(); foreach (var t in tenants) { NotifyHelper.SendAboutRestoreCompleted(t.TenantId, Notify); } } } else { CoreContext.TenantManager.RemoveTenant(tenant.TenantId); restoredTenant = CoreContext.TenantManager.GetTenant(columnMapper.GetTenantMapping()); restoredTenant.SetStatus(TenantStatus.Active); restoredTenant.TenantAlias = tenant.TenantAlias; restoredTenant.PaymentId = string.Empty; if (string.IsNullOrEmpty(restoredTenant.MappedDomain) && !string.IsNullOrEmpty(tenant.MappedDomain)) { restoredTenant.MappedDomain = tenant.MappedDomain; } CoreContext.TenantManager.SaveTenant(restoredTenant); // sleep until tenants cache expires Thread.Sleep(TimeSpan.FromMinutes(2)); NotifyHelper.SendAboutRestoreCompleted(restoredTenant.TenantId, Notify); } Percentage = 75; File.Delete(tempFile); Percentage = 100; } catch (Exception error) { Log.Error(error); Error = error; if (tenant != null) { tenant.SetStatus(TenantStatus.Active); CoreContext.TenantManager.SaveTenant(tenant); } } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } IsCompleted = true; } }
public void RunJob() { if (ThreadPriority.BelowNormal < Thread.CurrentThread.Priority) { Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; } var backupName = string.Format("{0}_{1:yyyy-MM-dd_HH-mm-ss}.{2}", CoreContext.TenantManager.GetTenant(TenantId).TenantAlias, DateTime.UtcNow, ArchiveFormat); var tempFile = Path.Combine(tempFolder, backupName); try { var backupTask = new BackupPortalTask(Log, TenantId, configPaths[currentRegion], tempFile); if (!BackupMail) { backupTask.IgnoreModule(ModuleName.Mail); } backupTask.IgnoreTable("tenants_tariff"); backupTask.ProgressChanged += (sender, args) => Percentage = 0.9 * args.Progress; backupTask.RunJob(); var backupStorage = BackupStorageFactory.GetBackupStorage(StorageType, TenantId); var storagePath = backupStorage.Upload(StorageBasePath, tempFile, UserId); Link = backupStorage.GetPublicLink(storagePath); var repo = BackupStorageFactory.GetBackupRepository(); repo.SaveBackupRecord( new BackupRecord { Id = (Guid)Id, TenantId = TenantId, IsScheduled = IsScheduled, FileName = Path.GetFileName(tempFile), StorageType = StorageType, StorageBasePath = StorageBasePath, StoragePath = storagePath, CreatedOn = DateTime.UtcNow, ExpiresOn = StorageType == BackupStorageType.DataStore ? DateTime.UtcNow.AddDays(1) : DateTime.MinValue }); Percentage = 100; if (UserId != Guid.Empty && !IsScheduled) { NotifyHelper.SendAboutBackupCompleted(TenantId, UserId, Link); } IsCompleted = true; } catch (Exception error) { Log.Error("RunJob - Params: {0}, Error = {1}", new { Id = Id, Tenant = TenantId, File = tempFile, BasePath = StorageBasePath, }, error); Error = error; IsCompleted = true; } finally { try { File.Delete(tempFile); } catch (Exception error) { Log.Error("can't delete file: {0}", error); } } }
private void DeleteExpiredBackups() { if (Monitor.TryEnter(cleanerLock)) { try { log.Debug("started to clean expired backups"); var backupRepository = BackupStorageFactory.GetBackupRepository(); var backupsToRemove = backupRepository.GetExpiredBackupRecords(); log.DebugFormat("found {0} backups which are expired", backupsToRemove.Count); if (!isStarted) { return; } foreach (var scheduledBackups in backupRepository.GetScheduledBackupRecords().GroupBy(r => r.TenantId)) { if (!isStarted) { return; } var schedule = backupRepository.GetBackupSchedule(scheduledBackups.Key); if (schedule != null) { var scheduledBackupsToRemove = scheduledBackups.OrderByDescending(r => r.CreatedOn).Skip(schedule.NumberOfBackupsStored).ToList(); if (scheduledBackupsToRemove.Any()) { log.DebugFormat("only last {0} scheduled backup records are to keep for tenant {1} so {2} records must be removed", schedule.NumberOfBackupsStored, schedule.TenantId, scheduledBackupsToRemove.Count); backupsToRemove.AddRange(scheduledBackupsToRemove); } } else { backupsToRemove.AddRange(scheduledBackups); } } foreach (var backupRecord in backupsToRemove) { if (!isStarted) { return; } try { var backupStorage = BackupStorageFactory.GetBackupStorage(backupRecord); if (backupStorage == null) { continue; } backupStorage.Delete(backupRecord.StoragePath); backupRepository.DeleteBackupRecord(backupRecord.Id); } catch (Exception error) { log.Warn("can't remove backup record: {0}", error); } } } catch (Exception error) { log.Error("error while cleaning expired backup records: {0}", error); } finally { Monitor.Exit(cleanerLock); } } }
static void Main(string[] args) { if (args.Any(x => x.ToLower() == "--config")) { string configCustomPath = args.GetArgValue("--config"); if (String.IsNullOrEmpty(configCustomPath)) { Console.WriteLine("Nieprawidłowa wartość parametru --config"); return; } Configuration.ConfigurationPath = configCustomPath; } if (args.Any(x => x.ToLower() == "--create-example-config")) { Configuration.CreateExampleConfigFile(); if (args.Length > 1) { Console.WriteLine("Używając parametru --create-example-config inne parametry są ignorowane."); } return; } if (args.Any(x => x.ToLower() == "--authorize")) { string providerName = args.GetArgValue("--authorize"); if (String.IsNullOrEmpty(providerName)) { Console.WriteLine("Brak wartości parametru --authorize."); return; } var config = Configuration.Get(); var provider = config.UploadProviders.FirstOrDefault(x => x.Name == providerName); if (provider == null) { Console.WriteLine($"Nie znaleziono providera o nazwie {providerName}"); return; } Console.WriteLine("Autoryzacja usług chmurowych zapisu kopii zapasowych..."); var storage = BackupStorageFactory.GetStorage(provider.ProviderClass); var token = storage.GetToken().GetAwaiter().GetResult(); Console.WriteLine("Twój token to: " + token); provider.Token = token; config.Update(); Console.WriteLine("Token został zapisany w konfiguracji aplikacji."); return; } if (args.Any(x => x.ToLower() == "--test-mail")) { new SmtpBackupInfo(new BackupInfo[0]).Send(); return; } Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); if (args.Any(x => x.ToLower() == "--backup")) { Application application = new Application(); var app = Task.Run(application.Run); app.Wait(); } else { WriteHelp(); } }
public void RunJob() { Tenant tenant = null; var tempFile = PathHelper.GetTempFileName(tempFolder); try { NotifyHelper.SendAboutRestoreStarted(TenantId, Notify); var storage = BackupStorageFactory.GetBackupStorage(StorageType, TenantId); storage.Download(StoragePath, tempFile); Percentage = 10; tenant = CoreContext.TenantManager.GetTenant(TenantId); tenant.SetStatus(TenantStatus.Restoring); CoreContext.TenantManager.SaveTenant(tenant); var columnMapper = new ColumnMapper(); columnMapper.SetMapping("tenants_tenants", "alias", tenant.TenantAlias, ((Guid)Id).ToString("N")); columnMapper.Commit(); var restoreTask = new RestorePortalTask(Log, TenantId, configPaths[currentRegion], tempFile, columnMapper); restoreTask.IgnoreTable("tenants_tariff"); restoreTask.ProgressChanged += (sender, args) => Percentage = (10d + 0.65 * args.Progress); restoreTask.RunJob(); CoreContext.TenantManager.RemoveTenant(tenant.TenantId); var restoredTenant = CoreContext.TenantManager.GetTenant(columnMapper.GetTenantMapping()); restoredTenant.SetStatus(TenantStatus.Active); restoredTenant.TenantAlias = tenant.TenantAlias; restoredTenant.PaymentId = string.Empty; if (string.IsNullOrEmpty(restoredTenant.MappedDomain) && !string.IsNullOrEmpty(tenant.MappedDomain)) { restoredTenant.MappedDomain = tenant.MappedDomain; } CoreContext.TenantManager.SaveTenant(restoredTenant); Percentage = 75; File.Delete(tempFile); // sleep until tenants cache expires Thread.Sleep(TimeSpan.FromMinutes(2)); Percentage = 100; NotifyHelper.SendAboutRestoreCompleted(restoredTenant.TenantId, Notify); } catch (Exception error) { Log.Error(error); Error = error; if (tenant != null) { tenant.SetStatus(TenantStatus.Active); CoreContext.TenantManager.SaveTenant(tenant); } } finally { if (File.Exists(tempFile)) { File.Delete(tempFile); } IsCompleted = true; } }
public async Task Run() { Configuration config = Configuration.Get(); List <BackupInfo> backupInfos = new List <BackupInfo>(); Stopwatch sw = new Stopwatch(); Stopwatch lsw = new Stopwatch(); sw.Start(); lsw.Start(); Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Start aplikacji..."); foreach (Database db in config.Databases) { BackupInfo info = new BackupInfo { Database = db.Name }; backupInfos.Add(info); StringWriter dbTraceStringWriter = new StringWriter(); TextWriterTraceListener dbTrace = new TextWriterTraceListener(dbTraceStringWriter); Trace.Listeners.Add(dbTrace); try { Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Tworzenie kopii bazy danych {db.Name}..."); lsw.Restart(); info.Path = new SqlBackup().Backup(db); Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Tworzenie kopii zakończone ({lsw.ElapsedMilliseconds} ms)..."); if (db.Zip) { Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Kompresowanie pliku {info.FileName}..."); lsw.Restart(); info.Path = new ZipFile().Create(info.Path, true, db.ZipPassword); Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Kompresja zakończona ({lsw.ElapsedMilliseconds} ms)."); } if (db.Upload) { var provider = config.UploadProviders.FirstOrDefault(x => x.Name == db.UploadProvider); if (provider == null) { throw new Exception($"Provider o nazwie {db.UploadProvider} nieznaleziony"); } Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Wysyłanie kopii zapasowej..."); lsw.Restart(); var storage = BackupStorageFactory.GetStorage(provider.ProviderClass); await storage.Upload(info.Path, provider.Token); Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Wysyłanie kopii zakończone ({lsw.ElapsedMilliseconds} ms)."); if (db.DeleteAfterUpload) { File.Delete(info.Path); Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Usunięto lokalną kopię zapasową."); } } info.Status = true; } catch (Exception ex) { info.Status = false; Trace.WriteLine(ex.Message); } Trace.Listeners.Remove(dbTrace); info.Info = dbTraceStringWriter.ToString(); dbTrace.Dispose(); dbTraceStringWriter.Dispose(); } Trace.WriteLine($"[{sw.ElapsedMilliseconds} ms] Koniec pracy aplikacji..."); sw.Stop(); lsw.Stop(); new SmtpBackupInfo(backupInfos).Send(); }