Exemplo n.º 1
0
        /// <exception cref="System.InvalidOperationException">
        ///   Thrown when the previous backup operation has not finished yet.
        /// </exception>
        /// <exception cref="System.NotImplementedException">
        ///   Thrown when the previous backup operation has not finished yet and it's marked to be resumed (`options.Resume` is `true`).
        ///   The restore operation doesn't support resume.
        /// </exception>
        private RestoreOperation CreateRestoreOperation(Models.RestorePlan plan)
        {
            var dao = new RestoreRepository();

            Models.Restore latest = dao.GetLatestByPlan(plan);
            MustResumeLastOperation = latest != null && latest.NeedsResume();

            if (MustResumeLastOperation && Options.Resume)
            {
                throw new NotImplementedException("The restore operation still does not support resuming.");
            }

            if (MustResumeLastOperation && !Options.Resume)
            {
                string message = string.Format("The restore (#{0}) has not finished yet."
                                               + " If it's still running, please, wait until it finishes,"
                                               + " otherwise you should resume it manually.",
                                               latest.Id);
                throw new InvalidOperationException(message);
            }

            // Create new restore or resume the last unfinished one.
            RestoreOperation obj = /* MustResumeLastOperation
                                    * ? new ResumeRestoreOperation(latest) as RestoreOperation
                                    * : */new NewRestoreOperation(plan) as RestoreOperation;

            obj.Updated += (sender2, e2) => RestoreUpdateStatsInfo(e2.Status, e2.TransferStatus);
            //obj.EventLog = ...
            //obj.TransferListControl = ...

            RestoreUpdateStatsInfo(RestoreOperationStatus.Unknown, TransferStatus.STOPPED);

            return(obj);
        }
Exemplo n.º 2
0
        public void Undo()
        {
            Assert.IsFalse(IsSaved);
            RestoreRepository daoRestore = new RestoreRepository();

            daoRestore.Refresh(Restore);
        }
Exemplo n.º 3
0
        public async Task <FileVersionerResults> DoRestore(Models.Restore restore, LinkedList <CustomVersionedFile> files, bool newRestore)
        {
            Assert.IsNotNull(restore);
            Assert.AreEqual(TransferStatus.RUNNING, restore.Status);
            Assert.IsNotNull(files);

            Results.Reset();

            await ExecuteOnBackround(() =>
            {
                RestoreRepository daoRestore = new RestoreRepository();
                Restore = daoRestore.Get(restore.Id);

                RestorePlanFileRepository daoRestorePlanFile = new RestorePlanFileRepository();
                AllFilesFromPlan = daoRestorePlanFile.GetAllByPlan(restore.RestorePlan).ToDictionary <Models.RestorePlanFile, string>(p => p.Path);

                Execute(restore, files, newRestore);

                Save();
            }, CancellationToken);

            return(Results);
        }
Exemplo n.º 4
0
        //
        // Summary:
        // 1. Create `RestorePlanFile`s and `RestoredFile`s as necessary and add them to the `Restore`.
        // 2. Insert/Update `Restore` and its `RestorededFile`s into the database, also saving
        //	  the `RestorePlanFile`s instances that may have been changed by step 1.2.
        // 3. Create versioned files and remove files that won't belong to this restore.
        //
        public void Save()
        {
            Assert.IsFalse(IsSaved);

            ISession session = NHibernateHelper.GetSession();

            RestoreRepository            daoRestore            = new RestoreRepository(session);
            RestorePlanFileRepository    daoRestorePlanFile    = new RestorePlanFileRepository(session);
            RestoredFileRepository       daoRestoredFile       = new RestoredFileRepository(session);
            BackupPlanPathNodeRepository daoBackupPlanPathNode = new BackupPlanPathNodeRepository(session);

            var FilesToTrack          = SuppliedFiles;
            var FilesToInsertOrUpdate = FilesToTrack;

            BlockPerfStats stats = new BlockPerfStats();

            using (ITransaction tx = session.BeginTransaction())
            {
                try
                {
                    // ------------------------------------------------------------------------------------

                    stats.Begin("STEP 1");

                    // 1. Create `RestorePlanFile`s and `RestoredFile`s as necessary and add them to the `Restore`.
                    foreach (Models.RestorePlanFile entry in FilesToInsertOrUpdate)
                    {
                        // Throw if the operation was canceled.
                        CancellationToken.ThrowIfCancellationRequested();

                        // 1.1 - Insert/Update RestorePlanFile's and RestoredFile's if they don't exist yet.

                        // IMPORTANT: It's important that we guarantee the referenced `RestorePlanFile` has a valid `Id`
                        // before we reference it elsewhere, otherwise NHibernate won't have a valid value to put on
                        // the `restore_plan_file_id` column.
                        daoRestorePlanFile.InsertOrUpdate(tx, entry);                         // Guarantee it's saved

                        Models.RestoredFile restoredFile = daoRestoredFile.GetByRestoreAndPath(Restore, entry.Path);
                        if (restoredFile == null)                         // If we're resuming, this should already exist.
                        {
                            // Create `RestoredFile`.
                            Models.BackupedFile backupedFile = entry.VersionedFile.UserData as Models.BackupedFile;
                            restoredFile = new Models.RestoredFile(Restore, entry, backupedFile);
                        }
                        restoredFile.UpdatedAt = DateTime.UtcNow;
                        daoRestoredFile.InsertOrUpdate(tx, restoredFile);

                        Restore.Files.Add(restoredFile);
                        //daoRestore.Update(tx, Restore);

                        ProcessBatch(session);
                    }

                    ProcessBatch(session, true);
                    stats.End();

                    // ------------------------------------------------------------------------------------

                    stats.Begin("STEP 2");

                    // 2. Insert/Update `Restore` and its `RestorededFile`s into the database, also saving
                    //	  the `RestorePlanFile`s instances that may have been changed by step 1.2.
                    {
                        daoRestore.Update(tx, Restore);
                    }

                    ProcessBatch(session, true);
                    stats.End();

                    // ------------------------------------------------------------------------------------

                    tx.Commit();
                }
                catch (OperationCanceledException)
                {
                    tx.Rollback();                     // Rollback the transaction
                    throw;
                }
                catch (Exception)
                {
                    tx.Rollback();                     // Rollback the transaction
                    throw;
                }
                finally
                {
                    //session.Close();
                    if (session.IsConnected)
                    {
                        session.Disconnect();
                    }
                }
            }

            IsSaved = true;

            // 3. Create versioned files and remove files that won't belong to this restore.
            TransferSet.Files = GetFilesToTransfer(Restore, SuppliedFiles);
        }
Exemplo n.º 5
0
        private void OnControlPlanQuery(object sender, ServerCommandEventArgs e)
        {
            string planType = e.Command.GetArgumentValue <string>("planType");
            Int32  planId   = e.Command.GetArgumentValue <Int32>("planId");

            ValidatePlanType(planType);

            bool isRunning   = IsPlanRunning(planType, planId);
            bool needsResume = false;
            bool isFinished  = false;

            bool isBackup  = planType.Equals(PlanTypeEnum.BACKUP.ToString().ToLowerInvariant());
            bool isRestore = planType.Equals(PlanTypeEnum.RESTORE.ToString().ToLowerInvariant());

            // Report to GUI.
            Commands.GuiReportPlanStatus report = new Commands.GuiReportPlanStatus();

            if (isBackup)
            {
                BackupRepository daoBackup = new BackupRepository();
                Models.Backup    latest    = daoBackup.GetLatestByPlan(new Models.BackupPlan {
                    Id = planId
                });

                needsResume = latest != null && latest.NeedsResume();
                isFinished  = latest != null && latest.IsFinished();

                if (isRunning)
                {
                    report.StartedAt = latest.StartedAt;
                }
                else if (isFinished)
                {
                    report.FinishedAt = latest.FinishedAt;
                }
            }
            else if (isRestore)
            {
                RestoreRepository daoRestore = new RestoreRepository();
                Models.Restore    latest     = daoRestore.GetLatestByPlan(new Models.RestorePlan {
                    Id = planId
                });

                needsResume = latest != null && latest.NeedsResume();
                isFinished  = latest != null && latest.IsFinished();

                if (isRunning)
                {
                    report.StartedAt = latest.StartedAt;
                }
                else if (isFinished)
                {
                    report.FinishedAt = latest.FinishedAt;
                }
            }

            bool isInterrupted = !isRunning && needsResume;

            Commands.OperationStatus status;
            // The condition order below is important because more than one flag might be true.
            if (isInterrupted)
            {
                status = Commands.OperationStatus.INTERRUPTED;
            }
            else if (needsResume)
            {
                status = Commands.OperationStatus.RESUMED;
            }
            else if (isRunning)
            {
                status = Commands.OperationStatus.STARTED;
            }
            else
            {
                status = Commands.OperationStatus.NOT_RUNNING;
            }

            report.Status = status;

            Handler.Send(e.Context, Commands.GuiReportOperationStatus(planType, planId, report));
        }