diff options
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs')
| -rw-r--r-- | Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs | 604 |
1 files changed, 0 insertions, 604 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs deleted file mode 100644 index d32df734d..000000000 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/BackupRestore/DefaultBackupManager.cs +++ /dev/null @@ -1,604 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Tango.Core; -using Tango.PPC.Common.Application; -using Tango.PPC.Common.BackupRestore; -using Tango.Core.ExtensionMethods; -using Tango.Core.DI; -using Tango.PPC.Common.Connection; -using System.IO; -using Tango.Core.Helpers; -using Tango.BL; -using Tango.Settings; -using Tango.Core.DB; -using System.Data.SqlClient; -using Ionic.Zip; -using Tango.BL.Entities; -using Tango.PPC.Common.Authentication; -using Tango.Integration.Upgrade; -using Tango.Core.IO; - -namespace Tango.PPC.Common.BackupRestore -{ - public class DefaultBackupManager : ExtendedObject, IBackupManager - { - private const string BACKUP_FILE_NAME = "Backup.json"; - private const string DATABASE_FILE_NAME = "Tango.bak"; - private const int VERSION = 1; - private const string PASSWORD = "1Creativity"; - - [TangoInject(TangoInjectMode.WhenAvailable)] - private IPPCApplicationManager _applicationManager; - - [TangoInject(TangoInjectMode.WhenAvailable)] - private IMachineProvider _machineProvider; - - [TangoInject(TangoInjectMode.WhenAvailable)] - private IAuthenticationProvider _authenticationProvider; - - public DefaultBackupManager() - { - TangoIOC.Default.Inject(this); - } - - public event EventHandler<BackupRestoreProgressEventArgs> Progress; - - public Task CreateBackup(string filePath, String name, BackupSettings settings) - { - return Task.Factory.StartNew(() => - { - var tempFolder = TemporaryManager.CreateFolder(); - - try - { - //Basic - LogManager.Log($"Starting backup operation to file '{filePath}'..."); - LogManager.Log($"Backup settings:\n{settings.ToJsonString()}"); - OnProgress(BackupRestoreStage.Initializing); - - LogManager.Log($"Temporary folder created on {tempFolder.Path}."); - - BackupFile backupFile = new BackupFile(); - backupFile.Version = VERSION; - backupFile.Date = DateTime.Now; - backupFile.Settings = settings; - backupFile.Name = name; - backupFile.MachineSerialNumber = _machineProvider.Machine.SerialNumber; - backupFile.ApplicationVersion = _applicationManager.Version.ToString(); - - //Firmware - try - { - LogManager.Log("Extracting firmware version from local tfp package..."); - using (var st = File.OpenRead(Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "firmware_package.tfp"))) - { - backupFile.FirmwareVersion = _machineProvider.MachineOperator.GetFirmwarePackageInfo(st).Result.FileDescriptors.SingleOrDefault(x => x.Destination == PMR.FirmwareUpgrade.VersionFileDestination.Mcu).Version; - } - } - catch (Exception ex) - { - throw new FileLoadException("Could extract the firmware version from the TFP package.", ex); - } - - LogManager.Log($"Backup file generated:\n{backupFile.ToJsonString()}"); - - if (settings.Mode == BackupMode.Jobs) - { - //Jobs - LogManager.Log("Starting jobs backup..."); - OnProgress(BackupRestoreStage.BackingupJobs); - using (ObservablesContext db = ObservablesContext.CreateDefault()) - { - var jobs = db.Jobs.ToList(); - - foreach (var job in jobs) - { - try - { - LogManager.Log($"Backing up job '{job.Name}'..."); - var jobFile = job.ToJobFile().Result; - backupFile.JobFiles.Add(jobFile); - - OnProgress(BackupRestoreStage.BackingupJobs, jobs.IndexOf(job) + 1, jobs.Count, false); - } - catch (Exception ex) - { - throw new InvalidOperationException($"Error extracting job {job.Name}.", ex); - } - } - } - LogManager.Log("Jobs backup completed."); - } - else - { - //User Settings - LogManager.Log("Backing up application settings..."); - OnProgress(BackupRestoreStage.BackingupSettings); - backupFile.SettingsFile = File.ReadAllText(SettingsManager.Default.FilePath); - - //Application Version - LogManager.Log("Backing up application files..."); - OnProgress(BackupRestoreStage.BackingupApplication); - - try - { - PathHelper.CopyDirectory(AssemblyHelper.GetCurrentAssemblyFolder(), tempFolder, true, (current, total) => - { - OnProgress(BackupRestoreStage.BackingupApplication, current, total, false); - }); - } - catch (Exception ex) - { - throw new IOException($"Error occurred while copying application files.", ex); - } - - //Database - LogManager.Log("Backing up database..."); - OnProgress(BackupRestoreStage.BackingupDatabase); - try - { - var dataSource = ObservablesContext.GetActualDataSource(); - using (var dbManager = DbManager.FromDataSource(dataSource)) - { - Directory.CreateDirectory("C:\\Backups"); - var dbBackupFile = $"C:\\Backups\\{DATABASE_FILE_NAME}"; - if (File.Exists(dbBackupFile)) - { - File.Delete(dbBackupFile); - } - dbManager.Backup(dataSource.Catalog, dbBackupFile); - File.Move(dbBackupFile, Path.Combine(tempFolder, DATABASE_FILE_NAME)); - } - } - catch (Exception ex) - { - throw new IOException("Error creating database backup", ex); - } - - LogManager.Log("Database backup completed."); - } - - //Backup.json - try - { - OnProgress(BackupRestoreStage.WritingConfiguration); - var backupFilePath = Path.Combine(tempFolder, BACKUP_FILE_NAME); - LogManager.Log($"Writing backup configuration file '{backupFilePath}'..."); - File.WriteAllText(backupFilePath, backupFile.ToJsonString()); - } - catch (Exception ex) - { - throw new IOException("Error writing backup configuration file.", ex); - } - - //Compression - LogManager.Log($"Generating {filePath}..."); - using (ZipFile zip = new ZipFile()) - { - zip.Password = PASSWORD; - zip.AddDirectory(tempFolder); - - zip.SaveProgress += (x, e) => - { - if (e.EventType == ZipProgressEventType.Saving_AfterWriteEntry) - { - LogManager.Log($"Compressing '{e.CurrentEntry.FileName}'..."); - OnProgress(BackupRestoreStage.CompressingFiles, e.EntriesSaved + 1, e.EntriesTotal, false); - } - }; - - zip.ParallelDeflateThreshold = -1; - zip.Save(filePath); - } - - //Done - LogManager.Log("Backup operation completed!!!"); - OnProgress(BackupRestoreStage.Done, 100, 100, false); - tempFolder.Delete(); - } - catch (Exception ex) - { - tempFolder.Delete(); - - OnProgress(BackupRestoreStage.Error, 100, 100, false); - LogManager.Log(ex, "Could not complete the backup operation."); - throw ex; - } - }); - } - - /// <summary> - /// Extracts the backup configuration from the specified backup file. - /// </summary> - /// <param name="filePath">The file path.</param> - /// <returns></returns> - public Task<BackupFile> ExtractBackupConfiguration(string filePath) - { - return Task.Factory.StartNew<BackupFile>(() => - { - using (ZipFile zip = ZipFile.Read(filePath)) - { - zip.Password = PASSWORD; - var reader = zip.Entries.SingleOrDefault(x => x.FileName == BACKUP_FILE_NAME).OpenReader(); - String json = String.Empty; - - using (StreamReader stReader = new StreamReader(reader)) - { - json = stReader.ReadToEnd(); - } - - var backupFile = BackupFile.FromJson(json); - reader.Close(); - reader.Dispose(); - return backupFile; - } - }); - } - - public Task<RestoreResult> Restore(string filePath, RestoreSettings settings) - { - TaskCompletionSource<RestoreResult> completionSource = new TaskCompletionSource<RestoreResult>(); - - String dbRollbackFile = null; - bool shouldRollback = false; - - Task.Factory.StartNew(() => - { - LogManager.Log($"Starting restore operation from file '{filePath}'..."); - OnProgress(BackupRestoreStage.Initializing); - - var tempFolder = TemporaryManager.CreateFolder(); - tempFolder.Persist = true; - - var restoreResult = new RestoreResult() { FolderPath = tempFolder }; - - try - { - LogManager.Log("Extracting backup file configuration..."); - - BackupFile backupFile = null; - - //Extract Configuration - try - { - OnProgress(BackupRestoreStage.ExtractingBackupConfiguration); - backupFile = ExtractBackupConfiguration(filePath).Result; - restoreResult.BackupFile = backupFile; - LogManager.Log($"Backup settings:\n{backupFile.Settings.ToJsonString()}"); - } - catch (Exception ex) - { - throw new IOException("Error extracting backup configuration.", ex); - } - - //Validate Version - if (backupFile.Version > VERSION) - { - throw new NotSupportedException($"Backup file version {backupFile} is not supported."); - } - - //Validate Machine Serial Number - if (backupFile.Settings.Mode == BackupMode.Full && backupFile.MachineSerialNumber != _machineProvider.Machine.SerialNumber) - { - throw new InvalidOperationException($"The specified backup file targets machine '{backupFile.MachineSerialNumber}'. Cannot perform the restore operation."); - } - - //Validate Machine State - LogManager.Log("Validating machine state..."); - OnProgress(BackupRestoreStage.ValidatingMachineState); - if (_machineProvider.MachineOperator.IsPrinting) - { - LogManager.Log("The machine is currently printing. Aborting!"); - throw new InvalidOperationException("Cannot perform restore operation while machine is dyeing."); - } - - if (backupFile.Settings.Mode == BackupMode.Full && _machineProvider.MachineOperator.State != Transport.TransportComponentState.Connected) - { - LogManager.Log("Backup is configured to restore the firmware but machine is not connected!"); - throw new InvalidOperationException("The restore operation is configured to restore the firmware version but the machine is currently disconnected."); - } - - //Create Restore Point - try - { - LogManager.Log("Creating database rollback file..."); - var dataSource = ObservablesContext.GetActualDataSource(); - using (var dbManager = DbManager.FromDataSource(dataSource)) - { - Directory.CreateDirectory("C:\\Backups"); - dbRollbackFile = $"C:\\Backups\\{Path.GetRandomFileName()}.bak"; - LogManager.Log($"Creating database rollback to '{dbRollbackFile}'..."); - dbManager.Backup(dataSource.Catalog, dbRollbackFile); - LogManager.Log("Database rollback created successfully."); - shouldRollback = true; - } - } - catch (Exception ex) - { - throw new InvalidDataException("Error creating database rollback file.", ex); - } - - if (backupFile.Settings.Mode == BackupMode.Jobs) - { - //Restore Jobs - OnProgress(BackupRestoreStage.RestoringJobs); - LogManager.Log("Starting jobs restore..."); - - using (ObservablesContext db = ObservablesContext.CreateDefault()) - { - var jobs = db.Jobs.ToList(); - var jobFiles = backupFile.JobFiles; - - if (settings.AllowDeleteJobs) - { - try - { - LogManager.Log("Removing existing jobs..."); - foreach (var job in jobs.ToList()) - { - LogManager.Log($"Removing job '{job.Name}'..."); - job.Delete(db); - jobs.Remove(job); - } - - db.SaveChanges(); - } - catch (Exception ex) - { - throw new Exception("Error removing existing jobs from database.", ex); - } - } - - foreach (var jobFile in jobFiles) - { - LogManager.Log($"Importing job '{jobFile.Name}'..."); - - try - { - var existingJob = jobs.FirstOrDefault(x => x.Name == jobFile.Name); - - if (existingJob != null) - { - if (settings.OverwriteExistingJobs) - { - try - { - LogManager.Log("Job already exist, overwriting..."); - - var newJob = Job.FromJobFile(jobFile, _machineProvider.Machine.Guid, null).Result; - newJob.Guid = existingJob.Guid; - - existingJob.Delete(db); - jobs.Remove(existingJob); - - db.SaveChanges(); - db.Jobs.Add(newJob); - db.SaveChanges(); - } - catch (Exception ex) - { - throw new InvalidOperationException("Error overwriting job.", ex); - } - } - } - else - { - var newJob = Job.FromJobFile(jobFile, _machineProvider.Machine.Guid, null).Result; - db.Jobs.Add(newJob); - } - } - catch (Exception ex) - { - throw new InvalidOperationException("Error importing job.", ex); - } - - OnProgress(BackupRestoreStage.RestoringJobs, jobFiles.IndexOf(jobFile) + 1, jobFiles.Count, false); - } - - OnProgress(BackupRestoreStage.RestoringJobs); - db.SaveChanges(); - } - - LogManager.Log("Jobs restored successfully."); - OnProgress(BackupRestoreStage.Done, 100, 100, false); - completionSource.SetResult(restoreResult); - } - else - { - //Extract zip file - LogManager.Log("Starting backup file extraction..."); - OnProgress(BackupRestoreStage.ExtractingContent); - try - { - using (ZipFile zip = new ZipFile(filePath)) - { - zip.Password = PASSWORD; - - zip.ExtractProgress += (x, e) => - { - if (e.EventType == ZipProgressEventType.Extracting_AfterExtractEntry) - { - LogManager.Log($"Extracting '{e.CurrentEntry.FileName}'..."); - OnProgress(BackupRestoreStage.ExtractingContent, e.EntriesExtracted + 1, e.EntriesTotal, false); - } - }; - - zip.ParallelDeflateThreshold = -1; - zip.ExtractAll(tempFolder); - } - } - catch (Exception ex) - { - throw new IOException("Error extracting backup content.", ex); - } - - //Overwrite settings - LogManager.Log("Validating user settings..."); - if (backupFile.SettingsFile != null) - { - try - { - LogManager.Log("Overwriting settings file..."); - OnProgress(BackupRestoreStage.RestoringSettings); - File.WriteAllText(SettingsManager.Default.FilePath, backupFile.SettingsFile); - } - catch (Exception ex) - { - throw new IOException("Error overwriting user settings.", ex); - } - } - else - { - LogManager.Log("No user settings, skipping..."); - } - - //Restore database - var backupFilePath = Path.Combine(tempFolder, DATABASE_FILE_NAME); - LogManager.Log($"Looking for file database backup on '{backupFilePath}'..."); - if (File.Exists(backupFilePath)) - { - LogManager.Log("Restoring database..."); - OnProgress(BackupRestoreStage.RestoringDatabase); - try - { - var dataSource = ObservablesContext.GetActualDataSource(); - using (var dbManager = DbManager.FromDataSource(dataSource)) - { - Directory.CreateDirectory("C:\\Backups"); - var dbBackupFile = $"C:\\Backups\\{DATABASE_FILE_NAME}"; - File.Copy(backupFilePath, dbBackupFile, true); - dbManager.Restore(dataSource.Catalog, dbBackupFile); - File.Delete(dbBackupFile); - } - } - catch (Exception ex) - { - throw new IOException("Error restoring database backup", ex); - } - - LogManager.Log("Database backup completed."); - } - else - { - LogManager.Log("Database backup file not found, skipping..."); - } - - //Remove extra files from application temp folder - OnProgress(BackupRestoreStage.RemovingTemporaryFiles); - LogManager.Log("Removing redundant files from temp folder..."); - try - { - File.Delete(backupFilePath); - } - catch { } - try - { - File.Delete(Path.Combine(tempFolder, BACKUP_FILE_NAME)); - } - catch { } - - //Update firmware - var tfpFile = Path.Combine(tempFolder, "firmware_package.tfp"); - LogManager.Log($"Looking for tfp file on '{tfpFile}'..."); - if (File.Exists(tfpFile)) - { - OnProgress(BackupRestoreStage.RestoringFirmware); - LogManager.Log("Restoring firmware version..."); - - var stream = new FileStream(tfpFile, FileMode.Open); - - _machineProvider.MachineOperator.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU | FirmwareUpgradeModes.TFP_PACKAGE; - - - var handler = _machineProvider.MachineOperator.UpgradeFirmware(stream, _machineProvider.Machine.IsDemo).Result; - handler.Failed += (_, ex) => - { - stream.Dispose(); - OnRestoreException(ex, completionSource, shouldRollback, dbRollbackFile, tempFolder); - }; - handler.Completed += (_, __) => - { - OnProgress(BackupRestoreStage.RestoringFirmware, 100, 100, false); - stream.Dispose(); - LogManager.Log("Full backup restored successfully."); - OnProgress(BackupRestoreStage.Done, 100, 100, false); - completionSource.SetResult(restoreResult); - }; - handler.Canceled += (_, __) => - { - stream.Dispose(); - OnRestoreException(new Exception("The operation has been canceled."), completionSource, shouldRollback, dbRollbackFile, tempFolder); - }; - handler.Progress += (_, e) => - { - OnProgress(BackupRestoreStage.RestoringFirmware, e.Current, e.Total, false); - }; - } - else - { - LogManager.Log("Firmware package file not found, skipping..."); - OnProgress(BackupRestoreStage.Done, 100, 100, false); - completionSource.SetResult(restoreResult); - } - } - } - catch (Exception ex) - { - OnRestoreException(ex, completionSource, shouldRollback, dbRollbackFile, tempFolder); - } - }); - - return completionSource.Task; - } - - private void OnRestoreException(Exception ex, TaskCompletionSource<RestoreResult> completionSource, bool shouldRollback, String dbRollbackFile, TemporaryFolder tempFolder) - { - if (shouldRollback) - { - LogManager.Log("Rolling back database changes..."); - - var dataSource = ObservablesContext.GetActualDataSource(); - using (var dbManager = DbManager.FromDataSource(dataSource)) - { - try - { - OnProgress(BackupRestoreStage.RollingBackChanges); - dbManager.Restore(dataSource.Catalog, dbRollbackFile); - LogManager.Log("Database restored successfully."); - } - catch (Exception e) - { - LogManager.Log(e, "Error rolling back database."); - } - finally - { - try - { - File.Delete(dbRollbackFile); - } - catch { } - } - } - } - - tempFolder.Delete(); - OnProgress(BackupRestoreStage.Error, 100, 100, false); - LogManager.Log(ex, "Could not complete the restore operation."); - completionSource.SetException(ex); - } - - protected virtual void OnProgress(BackupRestoreStage stage, double progress = 0, double maxProgress = 100, bool isIntermediate = true) - { - Progress?.Invoke(this, new BackupRestoreProgressEventArgs() - { - Stage = stage, - Progress = progress, - MaxProgress = maxProgress, - IsIntermediate = isIntermediate, - }); - } - } -} |
