示例#1
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <RestoreRequest>();

            DatabaseDocument databaseDocument = null;

            var databaseDocumentPath = Path.Combine(restoreRequest.BackupLocation, "Database.Document");

            if (File.Exists(databaseDocumentPath))
            {
                var databaseDocumentText = File.ReadAllText(databaseDocumentPath);
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id))
                                                                ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                                                : "A database name must be supplied if the restore location does not contain a valid Database.Document file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            if (databaseName == Constants.SystemDatabase)
            {
                return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (databaseDocument != null)
            {
                foreach (var setting in databaseDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename)))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);
            restoreRequest.DatabaseLocation  = ravenConfiguration.DataDirectory;
            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            await Task.Factory.StartNew(() =>
            {
                MaintenanceActions.Restore(ravenConfiguration, restoreRequest,
                                           msg =>
                {
                    restoreStatus.Messages.Add(msg);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                });

                if (databaseDocument == null)
                {
                    return;
                }

                databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
                if (restoreRequest.IndexesLocation != null)
                {
                    databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                }
                if (restoreRequest.JournalsLocation != null)
                {
                    databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                }
                databaseDocument.Id = databaseName;
                DatabasesLandlord.Protect(databaseDocument);
                DatabasesLandlord.SystemDatabase.Documents.Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument),
                                                               new RavenJObject(), null);

                restoreStatus.Messages.Add("The new database was created");
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                               RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
            }, TaskCreationOptions.LongRunning);

            return(GetEmptyMessage());
        }
示例#2
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                State = RestoreStatusState.Running, Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <DatabaseRestoreRequest>();

            DatabaseDocument databaseDocument = null;

            var databaseDocumentPath = MaintenanceActions.FindDatabaseDocument(restoreRequest.BackupLocation);

            if (File.Exists(databaseDocumentPath))
            {
                var databaseDocumentText = File.ReadAllText(databaseDocumentPath);
                databaseDocument = RavenJObject.Parse(databaseDocumentText).JsonDeserialization <DatabaseDocument>();
            }

            var databaseName = !string.IsNullOrWhiteSpace(restoreRequest.DatabaseName) ? restoreRequest.DatabaseName
                                                                   : databaseDocument == null ? null : databaseDocument.Id;

            if (string.IsNullOrWhiteSpace(databaseName))
            {
                var errorMessage = (databaseDocument == null || String.IsNullOrWhiteSpace(databaseDocument.Id))
                                                                ? "Database.Document file is invalid - database name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                                                : "A database name must be supplied if the restore location does not contain a valid Database.Document file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            if (databaseName == Constants.SystemDatabase)
            {
                return(GetMessageWithString("Cannot do an online restore for the <system> database", HttpStatusCode.BadRequest));
            }

            var existingDatabase = Database.Documents.GetDocumentMetadata("Raven/Databases/" + databaseName, null);

            if (existingDatabase != null)
            {
                return(GetMessageWithString("Cannot do an online restore for an existing database, delete the database " + databaseName + " and restore again.", HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                DatabaseName     = databaseName,
                IsTenantDatabase = true
            };

            if (databaseDocument != null)
            {
                foreach (var setting in databaseDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (File.Exists(Path.Combine(restoreRequest.BackupLocation, BackupMethods.Filename)))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Voron.TransactionalStorage).AssemblyQualifiedName;
            }
            else if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.DefaultStorageTypeName = typeof(Raven.Storage.Esent.TransactionalStorage).AssemblyQualifiedName;
            }

            ravenConfiguration.CustomizeValuesForDatabaseTenant(databaseName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.DataDirectory = ResolveTenantDataDirectory(restoreRequest.DatabaseLocation, databaseName, out documentDataDir);
            restoreRequest.DatabaseLocation  = ravenConfiguration.DataDirectory;

            string anotherRestoreResourceName;

            if (IsAnotherRestoreInProgress(out anotherRestoreResourceName))
            {
                if (restoreRequest.RestoreStartTimeout.HasValue)
                {
                    try
                    {
                        using (var cts = new CancellationTokenSource())
                        {
                            cts.CancelAfter(TimeSpan.FromSeconds(restoreRequest.RestoreStartTimeout.Value));
                            var token = cts.Token;
                            do
                            {
                                await Task.Delay(500, token);
                            }while (IsAnotherRestoreInProgress(out anotherRestoreResourceName));
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return(GetMessageWithString(string.Format("Another restore is still in progress (resource name = {0}). Waited {1} seconds for other restore to complete.", anotherRestoreResourceName, restoreRequest.RestoreStartTimeout.Value), HttpStatusCode.ServiceUnavailable));
                    }
                }
                else
                {
                    return(GetMessageWithString(string.Format("Another restore is in progress (resource name = {0})", anotherRestoreResourceName), HttpStatusCode.ServiceUnavailable));
                }
            }
            Database.Documents.Put(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, RavenJObject.FromObject(new RestoreInProgress
            {
                Resource = databaseName
            }), new RavenJObject(), null);

            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenRestoreStatusDocumentKey, null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    MaintenanceActions.Restore(ravenConfiguration, restoreRequest,
                                               msg =>
                    {
                        restoreStatus.Messages.Add(msg);
                        DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                       RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    });

                    if (databaseDocument == null)
                    {
                        return;
                    }

                    databaseDocument.Settings[Constants.RavenDataDir] = documentDataDir;
                    if (restoreRequest.IndexesLocation != null)
                    {
                        databaseDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                    }
                    if (restoreRequest.JournalsLocation != null)
                    {
                        databaseDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                    }

                    bool replicationBundleRemoved = false;
                    if (restoreRequest.DisableReplicationDestinations)
                    {
                        replicationBundleRemoved = TryRemoveReplicationBundle(databaseDocument);
                    }

                    databaseDocument.Id = databaseName;
                    DatabasesLandlord.Protect(databaseDocument);
                    DatabasesLandlord
                    .SystemDatabase
                    .Documents
                    .Put("Raven/Databases/" + databaseName, null, RavenJObject.FromObject(databaseDocument), new RavenJObject(), null);

                    restoreStatus.Messages.Add("The new database was created");
                    restoreStatus.State = RestoreStatusState.Completed;
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);

                    if (restoreRequest.GenerateNewDatabaseId)
                    {
                        GenerateNewDatabaseId(databaseName);
                    }

                    if (replicationBundleRemoved)
                    {
                        AddReplicationBundleAndDisableReplicationDestinations(databaseName);
                    }
                }
                catch (Exception e)
                {
                    restoreStatus.State = RestoreStatusState.Faulted;
                    restoreStatus.Messages.Add("Unable to restore database " + e.Message);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenRestoreStatusDocumentKey, null,
                                                                   RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    throw;
                }
                finally
                {
                    Database.Documents.Delete(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, null);
                }
            }, TaskCreationOptions.LongRunning);

            long id;

            Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription
            {
                StartTime = SystemTime.UtcNow,
                TaskType  = TaskActions.PendingTaskType.RestoreDatabase,
                Payload   = "Restoring database " + databaseName + " from " + restoreRequest.BackupLocation
            }, out id);


            return(GetMessageWithObject(new
            {
                OperationId = id
            }));
        }
示例#3
0
        public async Task <HttpResponseMessage> Restore()
        {
            if (EnsureSystemDatabase() == false)
            {
                return(GetMessageWithString("Restore is only possible from the system database", HttpStatusCode.BadRequest));
            }

            var restoreStatus = new RestoreStatus {
                State = RestoreStatusState.Running, Messages = new List <string>()
            };

            var restoreRequest = await ReadJsonObjectAsync <FilesystemRestoreRequest>();

            var fileSystemDocumentPath = FindFilesystemDocument(restoreRequest.BackupLocation);

            if (!File.Exists(fileSystemDocumentPath))
            {
                throw new InvalidOperationException("Cannot restore when the Filesystem.Document file is missing in the backup folder: " + restoreRequest.BackupLocation);
            }

            var filesystemDocumentText = File.ReadAllText(fileSystemDocumentPath);
            var filesystemDocument     = RavenJObject.Parse(filesystemDocumentText).JsonDeserialization <FileSystemDocument>();

            var filesystemName = !string.IsNullOrWhiteSpace(restoreRequest.FilesystemName) ? restoreRequest.FilesystemName
                                   : filesystemDocument == null ? null : filesystemDocument.Id;

            if (string.IsNullOrWhiteSpace(filesystemName))
            {
                var errorMessage = (filesystemDocument == null || String.IsNullOrWhiteSpace(filesystemDocument.Id))
                                ? Constants.FilesystemDocumentFilename + " file is invalid - filesystem name was not found and not supplied in the request (Id property is missing or null). This is probably a bug - should never happen."
                                : "A filesystem name must be supplied if the restore location does not contain a valid " + Constants.FilesystemDocumentFilename + " file";

                restoreStatus.Messages.Add(errorMessage);
                DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(new { restoreStatus }), new RavenJObject(), null);

                return(GetMessageWithString(errorMessage, HttpStatusCode.BadRequest));
            }

            var ravenConfiguration = new RavenConfiguration
            {
                FileSystemName = filesystemName,
            };

            if (filesystemDocument != null)
            {
                foreach (var setting in filesystemDocument.Settings)
                {
                    ravenConfiguration.Settings[setting.Key] = setting.Value;
                }
            }

            if (Directory.Exists(Path.Combine(restoreRequest.BackupLocation, "new")))
            {
                ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.EsentTypeName;
            }
            else
            {
                ravenConfiguration.FileSystem.DefaultStorageTypeName = InMemoryRavenConfiguration.VoronTypeName;
            }

            ravenConfiguration.CustomizeValuesForFileSystemTenant(filesystemName);
            ravenConfiguration.Initialize();

            string documentDataDir;

            ravenConfiguration.FileSystem.DataDirectory = ResolveTenantDataDirectory(restoreRequest.FilesystemLocation, filesystemName, out documentDataDir);
            restoreRequest.FilesystemLocation           = ravenConfiguration.FileSystem.DataDirectory;


            string anotherRestoreResourceName;

            if (IsAnotherRestoreInProgress(out anotherRestoreResourceName))
            {
                if (restoreRequest.RestoreStartTimeout.HasValue)
                {
                    try
                    {
                        using (var cts = new CancellationTokenSource())
                        {
                            cts.CancelAfter(TimeSpan.FromSeconds(restoreRequest.RestoreStartTimeout.Value));
                            var token = cts.Token;
                            do
                            {
                                await Task.Delay(500, token);
                            }while (IsAnotherRestoreInProgress(out anotherRestoreResourceName));
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        return(GetMessageWithString(string.Format("Another restore is still in progress (resource name = {0}). Waited {1} seconds for other restore to complete.", anotherRestoreResourceName, restoreRequest.RestoreStartTimeout.Value), HttpStatusCode.ServiceUnavailable));
                    }
                }
                else
                {
                    return(GetMessageWithString(string.Format("Another restore is in progress (resource name = {0})", anotherRestoreResourceName), HttpStatusCode.ServiceUnavailable));
                }
            }
            Database.Documents.Put(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, RavenJObject.FromObject(new RestoreInProgress
            {
                Resource = filesystemName
            }), new RavenJObject(), null);

            DatabasesLandlord.SystemDatabase.Documents.Delete(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, null);

            bool defrag;

            if (bool.TryParse(GetQueryStringValue("defrag"), out defrag))
            {
                restoreRequest.Defrag = defrag;
            }

            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(restoreRequest.FilesystemLocation))
                    {
                        ravenConfiguration.FileSystem.DataDirectory = restoreRequest.FilesystemLocation;
                    }

                    using (var transactionalStorage = RavenFileSystem.CreateTransactionalStorage(ravenConfiguration))
                    {
                        transactionalStorage.Restore(restoreRequest, msg =>
                        {
                            restoreStatus.Messages.Add(msg);
                            DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null,
                                                                           RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                        });
                    }

                    if (filesystemDocument == null)
                    {
                        return;
                    }

                    filesystemDocument.Settings[Constants.FileSystem.DataDirectory] = documentDataDir;

                    if (restoreRequest.IndexesLocation != null)
                    {
                        filesystemDocument.Settings[Constants.RavenIndexPath] = restoreRequest.IndexesLocation;
                    }
                    if (restoreRequest.JournalsLocation != null)
                    {
                        filesystemDocument.Settings[Constants.RavenTxJournalPath] = restoreRequest.JournalsLocation;
                    }
                    filesystemDocument.Id = filesystemName;

                    FileSystemsLandlord.Protect(filesystemDocument);

                    DatabasesLandlord.SystemDatabase.Documents.Put(Constants.FileSystem.Prefix + filesystemName, null, RavenJObject.FromObject(filesystemDocument), new RavenJObject(), null);

                    restoreStatus.State = RestoreStatusState.Completed;
                    restoreStatus.Messages.Add("The new filesystem was created");
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                }
                catch (Exception e)
                {
                    restoreStatus.State = RestoreStatusState.Faulted;
                    restoreStatus.Messages.Add("Unable to restore filesystem " + e.Message);
                    DatabasesLandlord.SystemDatabase.Documents.Put(RestoreStatus.RavenFilesystemRestoreStatusDocumentKey(filesystemName), null, RavenJObject.FromObject(restoreStatus), new RavenJObject(), null);
                    throw;
                }
                finally
                {
                    Database.Documents.Delete(RestoreInProgress.RavenRestoreInProgressDocumentKey, null, null);
                }
            }, TaskCreationOptions.LongRunning);

            long id;

            Database.Tasks.AddTask(task, new TaskBasedOperationState(task), new TaskActions.PendingTaskDescription
            {
                StartTime = SystemTime.UtcNow,
                TaskType  = TaskActions.PendingTaskType.RestoreFilesystem,
                Payload   = "Restoring filesystem " + filesystemName + " from " + restoreRequest.BackupLocation
            }, out id);

            return(GetMessageWithObject(new
            {
                OperationId = id
            }));
        }
示例#4
0
        internal override async Task <HttpResponseMessage> RunAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            string applicationNameUri;
            string serviceNameUri;
            string partitionId;
            var    fabricUri = await UtilityHelper.GetFabricUriFromRequstHeaderForPartitions(this.fabricRequestHeader, timeout, cancellationToken);

            this.ThrowInvalidArgumentIfNull(this.restoreRequest);

            await FabricClientHelper.IsFaultServiceExisting(timeout, cancellationToken);

            UtilityHelper.GetApplicationAndServicePartitionUri(fabricUri, out applicationNameUri, out serviceNameUri, out partitionId);

            BackupRestoreModel.BackupStorage backupStorage;
            if (this.restoreRequest.BackupStorage == null)
            {
                var backupProtection =
                    await this.BackupMappingStore.GetValueAsync(fabricUri, timeout, cancellationToken) ??
                    await this.BackupMappingStore.GetValueAsync(serviceNameUri, timeout, cancellationToken) ??
                    await this.BackupMappingStore.GetValueAsync(applicationNameUri, timeout, cancellationToken);

                if (backupProtection == null)
                {
                    throw new FabricPeriodicBackupNotEnabledException();
                }

                var backupPolicy =
                    await this.BackupPolicyStore.GetValueAsync(backupProtection.BackupPolicyName, timeout, cancellationToken);

                backupStorage = backupPolicy.Storage;
            }
            else
            {
                backupStorage = BackupRestoreModel.BackupStorage.FromBackupStorageView(this.restoreRequest.BackupStorage);
            }

            var recoveryPointManager = RecoveryPointManagerFactory.GetRecoveryPointManager(backupStorage);
            var backupDetails        = await recoveryPointManager.GetRecoveryPointDetailsAsync(this.restoreRequest.BackupLocation, cancellationToken);

            var retriveBackupDetails = backupDetails as RestorePoint;

            if (retriveBackupDetails == null)
            {
                throw new FabricException(StringResources.RestoreDetailsFetchFailed, FabricErrorCode.RestoreSafeCheckFailed);
            }

            if (!retriveBackupDetails.BackupId.Equals(this.restoreRequest.BackupId))
            {
                /*
                 * Add validation here for the request
                 */
                throw new FabricException(StringResources.BackupIdAndLocationMismatch,
                                          FabricErrorCode.RestoreSourceTargetPartitionMismatch);
            }


            var backupServicePartitionInformation = retriveBackupDetails.PartitionInformation;
            var servicePartitionInformation       = await FabricClientHelper.GetPartitionDetails(partitionId, timeout, cancellationToken);

            switch (servicePartitionInformation.Kind)
            {
            case ServicePartitionKind.Int64Range:
                var int64RangePartitionInformation       = servicePartitionInformation as System.Fabric.Int64RangePartitionInformation;
                var backupInt64RangePartitionInformation = backupServicePartitionInformation as BackupRestoreTypes.Int64RangePartitionInformation;

                if (backupInt64RangePartitionInformation == null ||
                    backupInt64RangePartitionInformation.HighKey != int64RangePartitionInformation.HighKey ||
                    backupInt64RangePartitionInformation.LowKey != int64RangePartitionInformation.LowKey)
                {
                    throw new FabricException(StringResources.InvalidInt64Keys,
                                              FabricErrorCode.RestoreSourceTargetPartitionMismatch);
                }

                break;

            case ServicePartitionKind.Named:
                var namedPartitionInformation       = servicePartitionInformation as System.Fabric.NamedPartitionInformation;
                var backupNamedPartitionInformation = backupServicePartitionInformation as BackupRestoreTypes.NamedPartitionInformation;

                if (backupNamedPartitionInformation == null ||
                    !namedPartitionInformation.Name.Equals(backupNamedPartitionInformation.Name))
                {
                    throw new FabricException(StringResources.InvalidNameKey,
                                              FabricErrorCode.RestoreSourceTargetPartitionMismatch);
                }

                break;

            case ServicePartitionKind.Singleton:
                var backupSingletonPartitionInformation = backupServicePartitionInformation as BackupRestoreTypes.SingletonPartitionInformation;
                if (backupSingletonPartitionInformation == null)
                {
                    throw new FabricException(StringResources.InvalidPartitionType,
                                              FabricErrorCode.RestoreSourceTargetPartitionMismatch);
                }

                break;
            }


            var backupLocations =
                await recoveryPointManager.GetBackupLocationsInBackupChainAsync(this.restoreRequest.BackupLocation, cancellationToken);

            var dataLossGuid       = Guid.NewGuid();
            var restoreRequestGuid = Guid.NewGuid();
            var restoreStatus      = new RestoreStatus(fabricUri, backupStorage, restoreRequestGuid, dataLossGuid, backupLocations, retriveBackupDetails);
            var restoreWorkItem    = new RestorePartitionWorkItem(serviceNameUri, partitionId, restoreRequestGuid, dataLossGuid, this.restoreTimeoutInMinutes);

            using (var transaction = this.StatefulService.StateManager.CreateTransaction())
            {
                await this.CheckForEitherBackupOrRestoreInProgress(fabricUri, timeout, cancellationToken, transaction);

                await this.WorkItemQueue.AddWorkItem(restoreWorkItem, timeout, cancellationToken, transaction);

                await this.RestoreStore.AddOrUpdateAsync(fabricUri, restoreStatus,
                                                         (fabricUri1, restoreStatus1) => restoreStatus, timeout, cancellationToken, transaction);

                await transaction.CommitAsync();
            }

            return(new HttpResponseMessage(HttpStatusCode.Accepted));
        }
        public async Task ProcessRestore(StatefulService statefulService, CancellationToken cancellationToken, string processQueueTypeTrace)
        {
            BackupRestoreTrace.TraceSource.WriteInfo(processQueueTypeTrace, "Processing the Restore for request Service Uri :  {0} , PartitionId {1}", this.ServiceUri, this.PartitionId);
            WorkItemStore workItemStore = await WorkItemStore.CreateOrGetWorkItemStore(statefulService);

            RestoreStore restoreStore = await RestoreStore.CreateOrGetRestoreStatusStore(statefulService);

            string fabricUri = UtilityHelper.GetBackupMappingKey(this.ServiceUri, this.PartitionId);
            PartitionDataLossProgress partitionDataLossProgress = await this.GetPartitionDataLossProgress(processQueueTypeTrace);

            if (this.RestoreStatusStateModel == RestoreStatusStateModel.TriggerDataLoss)
            {
                if (partitionDataLossProgress == null)
                {
                    bool isInitiateDataLossSuccess = await this.InitiateDataLoss(processQueueTypeTrace);

                    if (isInitiateDataLossSuccess)
                    {
                        this.RestoreStatusStateModel = RestoreStatusStateModel.DataLossTriggered;
                    }
                }
                await workItemStore.UpdateValueAsync(this.WorkItemGuid, this);

                BackupRestoreTrace.TraceSource.WriteInfo(processQueueTypeTrace, "RestoreStatusStateModel as DataLossTriggered for request Service Uri :  {0} , PartitionId {1}", this.ServiceUri, this.PartitionId);
            }
            if (this.RestoreStatusStateModel == RestoreStatusStateModel.DataLossTriggered)
            {
                RestoreStatus restoreStatus = null;
                do
                {
                    partitionDataLossProgress = await this.GetPartitionDataLossProgress(processQueueTypeTrace);

                    switch (partitionDataLossProgress.State)
                    {
                    case TestCommandProgressState.Running:
                    case TestCommandProgressState.RollingBack:
                    case TestCommandProgressState.Completed:
                        break;

                    case TestCommandProgressState.Cancelled:
                    case TestCommandProgressState.Faulted:
                    case TestCommandProgressState.ForceCancelled:
                        this.DataLossGuid = Guid.NewGuid();
                        await workItemStore.UpdateValueAsync(this.WorkItemGuid, this);

                        await this.InitiateDataLoss(processQueueTypeTrace);

                        break;
                    }
                    await Task.Delay(Constants.CheckRestoreTimeSpan, cancellationToken);

                    restoreStatus = await restoreStore.GetValueAsync(fabricUri);

                    if (restoreStatus.RestoreStatusState == RestoreState.Timeout && restoreStatus.RestoreRequestGuid.Equals(this.RestoreRequestGuid))
                    {
                        partitionDataLossProgress = await this.GetPartitionDataLossProgress(processQueueTypeTrace);

                        switch (partitionDataLossProgress.State)
                        {
                        case TestCommandProgressState.Running:
                        case TestCommandProgressState.RollingBack:
                            await this.CancelDataLoss(processQueueTypeTrace);

                            break;

                        case TestCommandProgressState.Cancelled:
                        case TestCommandProgressState.Faulted:
                        case TestCommandProgressState.ForceCancelled:
                        case TestCommandProgressState.Completed:
                            break;
                        }
                    }
                } while ((restoreStatus.RestoreStatusState == RestoreState.RestoreInProgress ||
                          restoreStatus.RestoreStatusState == RestoreState.Accepted) &&
                         this.RestoreRequestGuid.Equals(restoreStatus.RestoreRequestGuid) &&
                         !cancellationToken.IsCancellationRequested);
                cancellationToken.ThrowIfCancellationRequested();
            }
        }
示例#6
0
 public Restore(int restoreId, int backupId, DateTime date, DateTime executedDate, Guid clientId, RestoreStatus status = RestoreStatus.NoStatus)
 {
     RestoreId    = restoreId;
     BackupId     = backupId;
     Date         = date;
     ExecutedDate = executedDate;
     ClientId     = clientId;
     Status       = status;
 }
示例#7
0
 public void UpdateStatus(RestoreStatus status)
 {
     Status = status;
 }
示例#8
0
 private static void FileManager_OnFileRestore(object sender, RestoreStatus eventArg)
 {
     Console.WriteLine(eventArg.status.ToString());
     Console.WriteLine(eventArg.errorInfo);
     Console.ReadKey();
 }
示例#9
0
        //-----------------------------------------------------------------------------
        // dbRestore
        //-----------------------------------------------------------------------------
        /// <summary>
        /// Restores a previously backed up database. The <paramref name="sBackupPath"/> parameter
        /// and the <paramref name="restoreClient"/> parameter are mutually exclusive.  If the
        /// <paramref name="restoreClient"/> parameter is null, then the backup data will be read from
        /// <paramref name="sBackupPath"/>.  If <paramref name="restoreClient"/> is non-null,
        ///  <paramref name="sBackupPath"/> is ignored.
        /// </summary>
        /// <param name="sDbPath">
        /// The name of the control file of the database to restore.
        /// </param>
        /// <param name="sDataDir">
        /// The data file directory.  For more information see <see cref="dbCreate"/>.
        /// </param>
        /// <param name="sRflDir">
        /// The roll-forward log file directory.  For more information see <see cref="dbCreate"/>.
        /// </param>
        /// <param name="sBackupPath">
        /// The path to the backup files.  This may be null.  If
        /// non-null, it specifies the directory where the backup files which are
        /// to be restored are found.  If null, the <paramref name="restoreClient"/> parameter must be
        /// non-null.
        /// </param>
        /// <param name="sPassword">
        /// Password for the backup.  If non-null, the database key in
        /// the backup was wrapped in a password instead of the local NICI storage
        /// key.  This allows the database to be restored to a different machine if
        /// desired.  If null, the database can only be restored to the same machine
        /// where it originally existed.
        /// </param>
        /// <param name="restoreClient">
        /// An object implementing the <see cref="RestoreClient"/> interface.  This may be null.  If
        /// non-null, it is an object that knows how to get the backup data.
        /// </param>
        /// <param name="restoreStatus">
        /// An object implementing <see cref="RestoreStatus"/> interface.  This may be null.  If
        /// non-null, it is a callback object whose methods will be called to report
        /// restore progress.
        /// </param>
        public void dbRestore(
			string			sDbPath,
			string			sDataDir,
			string			sRflDir,
			string			sBackupPath,
			string			sPassword,
			RestoreClient	restoreClient,
			RestoreStatus	restoreStatus)
        {
            RCODE							rc;
            RestoreClientDelegate	restoreClientDelegate = null;
            RestoreClientCallback	fnRestoreClient = null;
            RestoreStatusDelegate	restoreStatusDelegate = null;
            RestoreStatusCallback	fnRestoreStatus = null;

            if (restoreClient != null)
            {
                restoreClientDelegate = new RestoreClientDelegate( restoreClient);
                fnRestoreClient = new RestoreClientCallback( restoreClientDelegate.funcRestoreClient);
            }
            if (restoreStatus != null)
            {
                restoreStatusDelegate = new RestoreStatusDelegate( restoreStatus);
                fnRestoreStatus = new RestoreStatusCallback( restoreStatusDelegate.funcRestoreStatus);
            }

            if ((rc = xflaim_DbSystem_dbRestore( m_pDbSystem, sDbPath, sDataDir, sRflDir, sBackupPath,
                sPassword, fnRestoreClient, fnRestoreStatus)) != 0)
            {
                throw new XFlaimException( rc);
            }
        }
示例#10
0
            public RestoreStatusDelegate(
				RestoreStatus	restoreStatus)
            {
                m_restoreStatus = restoreStatus;
            }