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 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 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); }
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 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 void DeleteBackup(Guid id) { var backupRepository = BackupStorageFactory.GetBackupRepository(); 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 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 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); } } }
public void DeleteSchedule(int tenantId) { BackupStorageFactory.GetBackupRepository().DeleteBackupSchedule(tenantId); }
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); } } }
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; } }