private RecoveryOperationStatus ValidatePrequisites(RecoveryOperation opContext) { RecoveryOperationStatus state = new RecoveryOperationStatus(RecoveryStatus.Success); state.JobIdentifier = opContext.JobIdentifer; try { // must check state transfer //if (_context.StatusLatch.IsAnyBitsSet(BucketStatus.UnderStateTxfr)) //{ // state.Status = RecoveryStatus.Success;//M_TODO: change this to false, once this state transfer code is complete // if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsInfoEnabled) // LoggerManager.Instance.RecoveryLogger.Info("ShardRecoveryManager.Validate()", opContext.JobIdentifer + " failed because node is in state transfer"); //} if (state.Status == RecoveryStatus.Success) { string path = string.Empty; string username = ""; string password = ""; Dictionary <string, Dictionary <string, string[]> > dbMap = new Dictionary <string, Dictionary <string, string[]> >(); switch (opContext.OpCode) { case RecoveryOpCodes.SubmitBackupJob: SubmitBackupOpParams _bckpParam = (SubmitBackupOpParams)opContext.Parameter; path = _bckpParam.PersistenceConfiguration.FilePath; dbMap = _bckpParam.PersistenceConfiguration.DbCollectionMap; username = _bckpParam.PersistenceConfiguration.UserName; password = _bckpParam.PersistenceConfiguration.Password; break; case RecoveryOpCodes.SubmitRestoreJob: SubmitRestoreOpParams _resParam = (SubmitRestoreOpParams)opContext.Parameter; path = Path.Combine(_resParam.PersistenceConfiguration.FilePath); username = _resParam.PersistenceConfiguration.UserName; password = _resParam.PersistenceConfiguration.Password; dbMap = _resParam.PersistenceConfiguration.DbCollectionMap; List <string> shardNameList = new List <string>(); shardNameList.Add(_context.LocalShardName); Impersonation impersonation = null; bool isSharedPath = RecoveryFolderStructure.PathIsNetworkPath(path); if (isSharedPath) { impersonation = new Impersonation(username, password); } state = RecoveryFolderStructure.ValidateFolderStructure(path, RecoveryJobType.DataRestore, false, shardNameList); if (isSharedPath) { impersonation.Dispose(); } if (state.Status == RecoveryStatus.Failure) { if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("ShardRecoveryManager.Validate()", state.Message); } return(state); } else { #region validate files string folderName = string.Empty; string fileName = dbMap.First().Key; string folderPath = Path.Combine(path, folderName); string filePath = Path.Combine(folderPath, fileName); isSharedPath = RecoveryFolderStructure.PathIsNetworkPath(folderPath); bool fileExists = false; if (isSharedPath) { BackupFile file = new BackupFile(fileName, folderPath, null, null); impersonation = new Impersonation(username, password); fileExists = File.Exists(filePath); impersonation.Dispose(); } else { fileExists = File.Exists(filePath); } if (fileExists) { BackupFile file = new BackupFile(fileName, folderPath, username, password); Alachisoft.NosDB.Core.Recovery.Persistence.BackupFile.Header header = file.ReadFileHeader(); if (!header.Database.ToLower().Equals(dbMap.First().Key)) { state.Status = RecoveryStatus.Failure; state.Message = "Provided file does not contain the source database " + fileName; file.Close(); return(state); } file.Close(); } else { state.Status = RecoveryStatus.Failure; state.Message = "No file exists in the given folder"; return(state); } #endregion } break; } // this will only be false for backup if (!Directory.Exists(path)) { try { Impersonation impersonation = null; if (RecoveryFolderStructure.PathIsNetworkPath(path)) { impersonation = new Impersonation(username, password); } Directory.CreateDirectory(path); if (dbMap.Count > 0) { // check space for backup job long size = 0; foreach (string db in dbMap.Keys) { DatabaseStore database = _context.DatabasesManager.GetDatabase(db) as DatabaseStore; size = database.Size; } ulong availableFreeSpace = Util.DirectoryUtil.GetDiskFreeSpace(path); ulong requiredSize = (ulong)size; if (availableFreeSpace > requiredSize) { state.Status = RecoveryStatus.Success; } else { state.Status = RecoveryStatus.Failure; state.Message = "Available memory is less than the required memory for backup"; return(state); } } if (impersonation != null) { impersonation.Dispose(); } } catch (Exception ex) { state.Status = RecoveryStatus.Failure; state.Message = ex.Message; if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("ShardRecoveryManager.Validate()", ex.ToString()); } } } } } catch (Exception exp) { state.Status = RecoveryStatus.Failure; state.Message = exp.ToString(); if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("ShardRecoveryManager.Validate()", opContext.JobIdentifer + " : " + exp.ToString()); } } return(state); }
private RecoveryOperationStatus EnsurePreRequisites(RecoveryConfiguration config, object additionalParams) { RecoveryOperationStatus state = new RecoveryOperationStatus(RecoveryStatus.Failure); state.JobIdentifier = config.Identifier; Impersonation impersonation = null; if (RecoveryFolderStructure.PathIsNetworkPath(config.RecoveryPath)) { impersonation = new Impersonation(config.UserName, config.Password); } List <string> shardNameList = new List <string>(); ClusterInfo clusterInfo = GetConfiguredClusters(config.Cluster); shardNameList.AddRange(clusterInfo.ShardInfo.Keys); state = RecoveryFolderStructure.ValidateFolderStructure(config.RecoveryPath, config.JobType, true, shardNameList); if (state.Status == RecoveryStatus.Failure) { if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("RecoveryManager.EnsurePreRequisites()", config.RecoveryPath + " : " + state.Message); } } if (state.Status == RecoveryStatus.Success) { CsBackupableEntities entity = (CsBackupableEntities)additionalParams; #region validate db Name switch (config.JobType) { case RecoveryJobType.ConfigRestore: case RecoveryJobType.Restore: state = DatabaseExists(config.DatabaseMap, entity, config.JobType); if (state.Status == RecoveryStatus.Failure) { return(state); } break; case RecoveryJobType.ConfigBackup: case RecoveryJobType.DataBackup: case RecoveryJobType.FullBackup: state = DatabaseExists(config.DatabaseMap, entity, config.JobType); if (state.Status == RecoveryStatus.Failure) { return(state); } break; } state.Status = RecoveryStatus.Success; #endregion #region validate files if (config.JobType == RecoveryJobType.Restore) { string configPath = Path.Combine(config.RecoveryPath, RecoveryFolderStructure.CONFIG_SERVER); string filePath = Path.Combine(configPath, RecoveryFolderStructure.CONFIG_SERVER); if (File.Exists(filePath)) { BackupFile file = new BackupFile(RecoveryFolderStructure.CONFIG_SERVER, configPath, config.UserName, config.Password); Alachisoft.NosDB.Core.Recovery.Persistence.BackupFile.Header header = file.ReadFileHeader(); if (!header.Database.ToLower().Equals(config.DatabaseMap.First().Key)) { state.Status = RecoveryStatus.Failure; state.Message = "Provided file does not contain the source database " + config.DatabaseMap.First().Key; } file.Close(); } else { state.Status = RecoveryStatus.Failure; state.Message = "No file exists in the given folder"; } } #endregion if (impersonation != null) { impersonation.Dispose(); } } if (state.Status == RecoveryStatus.Failure) { if (LoggerManager.Instance.RecoveryLogger != null && LoggerManager.Instance.RecoveryLogger.IsErrorEnabled) { LoggerManager.Instance.RecoveryLogger.Error("RecoveryManager.EnsurePreRequisites()", state.Message); } } return(state); }