/// <summary> /// Gets the first filesystem in lower tier for storage purpose. /// </summary> /// <param name="filesystem">The current filesystem</param> /// <returns></returns> public ServerFilesystemInfo GetLowerTierFilesystemForStorage(ServerFilesystemInfo filesystem) { lock (SyncLock) { List <FilesystemTierEnum> lowerTiers = FindLowerTierFilesystems(filesystem); if (lowerTiers == null || lowerTiers.Count == 0) { return(null); } List <ServerFilesystemInfo> list = new List <ServerFilesystemInfo>(); foreach (FilesystemTierEnum tier in lowerTiers) { list.AddRange(_tierInfo[tier]); } CollectionUtils.Remove(list, fs => !fs.Writeable); list = CollectionUtils.Sort(list, FilesystemSorter.SortByFreeSpace); ServerFilesystemInfo lowtierFilesystem = CollectionUtils.FirstElement(list); if (lowtierFilesystem == null) { return(null); } return(new ServerFilesystemInfo(lowtierFilesystem));//return a copy } }
public ServerFilesystemInfo(ServerFilesystemInfo copy) { _filesystem = copy.Filesystem; _online = copy.Online; _freeBytes = copy.FreeBytes; _totalBytes = copy.TotalBytes; }
/// <summary> /// Checks for a storage location for the study in the database, and creates a new location /// in the database if it doesn't exist. /// </summary> /// <param name="partition">The partition where the study is being sent to</param> /// <param name="created"></param> /// <param name="studyDate"></param> /// <param name="studyInstanceUid"></param> /// <param name="syntax"></param> /// <param name="updateContext">The update context to create the study on</param> /// <returns>A <see cref="StudyStorageLocation"/> instance.</returns> public StudyStorageLocation GetOrCreateWritableStudyStorageLocation(string studyInstanceUid, string studyDate, TransferSyntax syntax, IUpdateContext updateContext, ServerPartition partition, out bool created) { created = false; StudyStorageLocation location; try { GetWritableStudyStorageLocation(partition.Key, studyInstanceUid, StudyRestore.True, StudyCache.True, out location); return(location); } catch (StudyNotFoundException) { } FilesystemSelector selector = new FilesystemSelector(Instance); ServerFilesystemInfo filesystem = selector.SelectFilesystem(); if (filesystem == null) { throw new NoWritableFilesystemException(); } IInsertStudyStorage locInsert = updateContext.GetBroker <IInsertStudyStorage>(); InsertStudyStorageParameters insertParms = new InsertStudyStorageParameters { ServerPartitionKey = partition.GetKey(), StudyInstanceUid = studyInstanceUid, Folder = ResolveStorageFolder(partition.Key, studyInstanceUid, studyDate, updateContext, false /* set to false for optimization because we are sure it's not in the system */), FilesystemKey = filesystem.Filesystem.GetKey(), QueueStudyStateEnum = QueueStudyStateEnum.Idle }; if (syntax.LosslessCompressed) { insertParms.TransferSyntaxUid = syntax.UidString; insertParms.StudyStatusEnum = StudyStatusEnum.OnlineLossless; } else if (syntax.LossyCompressed) { insertParms.TransferSyntaxUid = syntax.UidString; insertParms.StudyStatusEnum = StudyStatusEnum.OnlineLossy; } else { insertParms.TransferSyntaxUid = syntax.UidString; insertParms.StudyStatusEnum = StudyStatusEnum.Online; } location = locInsert.FindOne(insertParms); created = true; return(location); }
/// <summary> /// Find lower tier filesystems. /// </summary> /// <param name="filesystem"></param> /// <returns></returns> private List <FilesystemTierEnum> FindLowerTierFilesystems(ServerFilesystemInfo filesystem) { List <FilesystemTierEnum> lowerTiers = new List <FilesystemTierEnum>(); foreach (FilesystemTierEnum tier in _tierInfo.Keys) { if (tier.Enum > filesystem.Filesystem.FilesystemTierEnum.Enum) { lowerTiers.Add(tier); } } return(lowerTiers); }
/// <summary> /// Helper method to verify if the specified <see cref="StudyStorageLocation"/> /// is writable and throw <see cref="FilesystemNotWritableException"/> if it is not. /// </summary> /// <param name="location"></param> public void EnsureStorageLocationIsWritable(StudyStorageLocation location) { ServerFilesystemInfo fs = GetFilesystemInfo(location.FilesystemKey); if (!fs.Enable) { throw new FilesystemNotWritableException(fs.Filesystem.FilesystemPath) { Reason = "It is disabled" } } ; if (!fs.Online) { throw new FilesystemNotWritableException(fs.Filesystem.FilesystemPath) { Reason = "It is offline/unreachable" } } ; if (fs.ReadOnly) { throw new FilesystemNotWritableException(fs.Filesystem.FilesystemPath) { Reason = "It is read-only" } } ; if (fs.Full) { throw new FilesystemNotWritableException(fs.Filesystem.FilesystemPath) { Reason = "It is full" } } ; }
public static int SortByFreeSpace(ServerFilesystemInfo fs1, ServerFilesystemInfo fs2) { Platform.CheckForNullReference(fs1, "fs1"); Platform.CheckForNullReference(fs2, "fs2"); Platform.CheckForNullReference(fs1.Filesystem, "fs1.Filesystem"); Platform.CheckForNullReference(fs2.Filesystem, "fs2.Filesystem"); if (fs1 == fs2) { return(0); } if (fs1.Filesystem.FilesystemTierEnum.Enum.Equals(fs2.Filesystem.FilesystemTierEnum.Enum)) { // descending order on available size.. smaller margin means less available space return(fs2.HighwaterMarkMargin.CompareTo(fs1.HighwaterMarkMargin)); } else { // ascending order on tier return(fs1.Filesystem.FilesystemTierEnum.Enum.CompareTo(fs2.Filesystem.FilesystemTierEnum.Enum)); } }
public ServerFilesystemInfo SelectFilesystem() { IList <ServerFilesystemInfo> list = new List <ServerFilesystemInfo>(_monitor.GetFilesystems()); IList <ServerFilesystemInfo> writableFS = CollectionUtils.Select(list, delegate(ServerFilesystemInfo fs) { return(fs.Writeable); }); StringBuilder log = new StringBuilder(); if (writableFS == null || writableFS.Count == 0) { log.AppendLine("No writable storage found"); foreach (ServerFilesystemInfo fs in list) { log.AppendLine(string.Format("\t{0} : {1}", fs.Filesystem.Description, fs.StatusString)); } Platform.Log(LogLevel.Warn, log.ToString()); return(null); } writableFS = CollectionUtils.Sort(writableFS, FilesystemSorter.SortByFreeSpace); ServerFilesystemInfo selectedFS = CollectionUtils.FirstElement(writableFS); Platform.CheckForNullReference(selectedFS, "selectedFS"); return(selectedFS); }
/// <summary> /// Load filesystem information from the database. /// </summary> private void LoadFilesystems() { bool changed = false; lock (SyncLock) { try { List <FilesystemTierEnum> tiers = FilesystemTierEnum.GetAll(); // sorted by enum values tiers.Sort((tier1, tier2) => tier1.Enum.CompareTo(tier2.Enum)); _tierInfo = new TierInfo(); foreach (FilesystemTierEnum tier in tiers) { _tierInfo.Add(tier, new List <ServerFilesystemInfo>()); } using (IReadContext read = _store.OpenReadContext()) { IFilesystemEntityBroker filesystemSelect = read.GetBroker <IFilesystemEntityBroker>(); FilesystemSelectCriteria criteria = new FilesystemSelectCriteria(); IList <Filesystem> filesystemList = filesystemSelect.Find(criteria); foreach (Filesystem filesystem in filesystemList) { if (_filesystemList.ContainsKey(filesystem.Key)) { if ((filesystem.HighWatermark != _filesystemList[filesystem.Key].Filesystem.HighWatermark) || (filesystem.LowWatermark != _filesystemList[filesystem.Key].Filesystem.LowWatermark)) { Platform.Log(LogLevel.Info, "Watermarks have changed for filesystem {0}, Low: {1}, High: {2}", filesystem.Description, filesystem.LowWatermark, filesystem.HighWatermark); } _filesystemList[filesystem.Key].Filesystem = filesystem; _tierInfo[filesystem.FilesystemTierEnum].Add(_filesystemList[filesystem.Key]); } else { ServerFilesystemInfo info = new ServerFilesystemInfo(filesystem); _filesystemList.Add(filesystem.Key, info); _tierInfo[filesystem.FilesystemTierEnum].Add(info); info.LoadFreeSpace(); changed = true; } } } if (changed && _changedListener != null) { EventsHelper.Fire(_changedListener, this, new FilesystemChangedEventArgs(this)); } } catch (Exception ex) { Platform.Log(LogLevel.Error, ex, "Exception has occurred while updating the filesystem list from the datbase. Retry later"); } } }
/// <summary> /// Returns a value indicating whether the filesystem with the specified key /// is writable. /// </summary> /// <param name="key"></param> /// <returns></returns> public bool IsWritable(ServerEntityKey key) { ServerFilesystemInfo fs = GetFilesystemInfo(key); return(fs.Writeable); }