//M_TODO: must Specify DB name in case of shard job, so a separate job is created, for now this will run multiple times and override job if more //than one db is specified. private JobInfoObject CreateRestoreJob(RecoveryOperation opContext) { JobInfoObject infoObject = null; RecoveryJobBase dataJob = null; #region RestoreJob SubmitRestoreOpParams resParam = (SubmitRestoreOpParams)opContext.Parameter; foreach (string db in resParam.PersistenceConfiguration.DbCollectionMap.Keys) { // create handler object // Note: this is kept inside the loop with the assumption that a seperate info object is to be kept for each database in complete cluster job infoObject = new JobInfoObject(opContext.JobIdentifer, _context.LocalShardName, _context.LocalAddress.ip, _context.ClusterName, RecoveryJobType.DataRestore, resParam.PersistenceConfiguration.FilePath); string destination = resParam.PersistenceConfiguration.DbCollectionMap[db].Keys.First(); // create DataJob dataJob = new DatabaseRestoreJob(opContext.JobIdentifer, _context, destination, resParam.PersistenceConfiguration.DbCollectionMap[db][destination].ToList <string>(), infoObject.RecoveryPersistenceManager, _context.ClusterName); dataJob.RegisterProgressHandler(this); infoObject.AddJob(dataJob); // set persistence configuration if (resParam.PersistenceConfiguration.FileName == null) { resParam.PersistenceConfiguration.FileName = new List <string>(); resParam.PersistenceConfiguration.FileName.Add(db);//add name of all databases for shard level job } infoObject.RecoveryPersistenceManager.SetJobConfiguration(RecoveryJobType.DataRestore, resParam.PersistenceConfiguration, db, 1); } #endregion return(infoObject); }
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); }