示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
 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);
         }
     }
 }
示例#5
0
        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);
        }
示例#6
0
 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
     });
 }
示例#7
0
 public BackupService(
     IOptionsMonitor <ILog> options,
     BackupStorageFactory backupStorageFactory,
     BackupWorker backupWorker,
     BackupRepository backupRepository,
     ConfigurationExtension configuration)
 {
     Log = options.CurrentValue;
     BackupStorageFactory = backupStorageFactory;
     BackupWorker         = backupWorker;
     BackupRepository     = backupRepository;
     Configuration        = configuration;
 }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        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);
                }
            }
        }
示例#11
0
 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);
         }
     }
 }
示例#12
0
        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);
        }
示例#13
0
 public void DeleteSchedule(int tenantId)
 {
     BackupStorageFactory.GetBackupRepository().DeleteBackupSchedule(tenantId);
 }
示例#14
0
            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;
                }
            }
示例#15
0
            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);
                }
            }
        }
示例#17
0
        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();
            }
        }
示例#18
0
            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;
                }
            }
示例#19
0
        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();
        }