/// <summary> /// Retrieves the storage location from the database for the specified study storage key. Checks if the filesystem is online. /// </summary> /// <param name="studyStorageKey"></param> /// <param name="location"></param> /// <returns></returns> public bool GetWritableStudyStorageLocation(ServerEntityKey studyStorageKey, out StudyStorageLocation location) { // NOTE: THIS METHOD SHOULD NOT LOAD THE RECORD FROM THE CACHE using (ServerExecutionContext context = new ServerExecutionContext()) { IQueryStudyStorageLocation procedure = context.ReadContext.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters { StudyStorageKey = studyStorageKey }; IList <StudyStorageLocation> locationList = procedure.Find(parms); foreach (StudyStorageLocation studyLocation in locationList) { string reason; if (CheckFilesystemOnline(studyLocation.FilesystemKey, out reason)) { location = studyLocation; return(true); } } // TODO: throw new FilesystemIsNotWritableException(); location = null; return(false); } }
/// <summary> /// Gets the <see cref="StudyStorageLocation"/> for the study associated with the specified <see cref="WorkQueue"/> item. /// </summary> /// <param name="item"></param> /// <returns></returns> static public StudyStorageLocation GetLoadStorageLocation(WorkQueue item) { IQueryStudyStorageLocation select = HttpContextData.Current.ReadContext.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters(); parms.StudyStorageKey = item.StudyStorageKey; IList <StudyStorageLocation> storages = select.Find(parms); if (storages == null || storages.Count == 0) { Platform.Log(LogLevel.Error, "Unable to find storage location for WorkQueue item: {0}", item.Key.ToString()); throw new ApplicationException("Unable to find storage location for WorkQueue item."); } if (storages.Count > 1) { Platform.Log(LogLevel.Warn, "WorkQueueController:LoadWritableStorageLocation: multiple study storage found for work queue item {0}", item.Key.Key); } return(storages[0]); }
public IList <StudyStorageLocation> GetStudyStorageLocation(Study study) { Platform.CheckForNullReference(study, "Study"); IQueryStudyStorageLocation select = HttpContext.Current.GetSharedPersistentContext().GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters { StudyStorageKey = study.StudyStorageKey }; IList <StudyStorageLocation> storage = select.Find(parms); if (storage == null) { storage = new List <StudyStorageLocation>(); Platform.Log(LogLevel.Warn, "Unable to find storage location for Study item: {0}", study.GetKey().ToString()); } if (storage.Count > 1) { Platform.Log(LogLevel.Warn, "StudyController:GetStudyStorageLocation: multiple study storage found for study {0}", study.GetKey().Key); } return(storage); }
/// <summary> /// Retrieves the storage location from the database for the specified study. Checks if the filesystem is writable. /// </summary> /// <param name="location">The output storage location</param> /// <param name="partitionKey">The primark key of the ServerPartition table.</param> /// <param name="studyInstanceUid">The Study Instance UID of the study</param> /// <param name="cache">Should the study location be cached?</param> /// <param name="restore">If nearline, should the study be restored?</param> /// <returns></returns> public void GetWritableStudyStorageLocation(ServerEntityKey partitionKey, string studyInstanceUid, StudyRestore restore, StudyCache cache, out StudyStorageLocation location) { using (var context = new ServerExecutionContext()) { string reason; if (cache == StudyCache.True) { location = _storageLocationCache.GetCachedStudy(partitionKey, studyInstanceUid); if (location != null) { if (CheckFilesystemWriteable(location.FilesystemKey, out reason)) { return; } } } else { location = null; } IQueryStudyStorageLocation procedure = context.ReadContext.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters { ServerPartitionKey = partitionKey, StudyInstanceUid = studyInstanceUid }; IList <StudyStorageLocation> locationList = procedure.Find(parms); bool found = false; FilesystemNotWritableException x = new FilesystemNotWritableException(); foreach (StudyStorageLocation studyLocation in locationList) { if (CheckFilesystemWriteable(studyLocation.FilesystemKey, out reason)) { location = studyLocation; if (cache == StudyCache.True) { _storageLocationCache.AddCachedStudy(location); } return; } found = true; x.Reason = reason; x.Path = studyLocation.StudyFolder; } if (found) { throw x; } CheckForStudyRestore(context.ReadContext, partitionKey, studyInstanceUid, restore); } }
/// <summary> /// Retrieves the storage location from the database for the specified study. Checks if the filesystem is readable. /// </summary> /// <param name="partitionKey"></param> /// <param name="studyInstanceUid"></param> /// <param name="restore"></param> /// <param name="cache"></param> /// <param name="location"></param> public void GetReadableStudyStorageLocation(ServerEntityKey partitionKey, string studyInstanceUid, StudyRestore restore, StudyCache cache, out StudyStorageLocation location) { using (ServerExecutionContext context = new ServerExecutionContext()) { // Get the cached value, if it exists, otherwise fall down and recheck // and handle any nearline issues below location = _storageLocationCache.GetCachedStudy(partitionKey, studyInstanceUid); if (location != null) { string reason; if (CheckFilesystemReadable(location.FilesystemKey, out reason)) { return; } } IQueryStudyStorageLocation procedure = context.ReadContext.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters { StudyInstanceUid = studyInstanceUid, ServerPartitionKey = partitionKey }; IList <StudyStorageLocation> locationList = procedure.Find(parms); bool foundStudy = false; FilesystemNotReadableException x = new FilesystemNotReadableException(); foreach (StudyStorageLocation studyLocation in locationList) { string reason; if (CheckFilesystemReadable(studyLocation.FilesystemKey, out reason)) { location = studyLocation; if (cache == StudyCache.True) { _storageLocationCache.AddCachedStudy(location); } return; } foundStudy = true; x.Path = studyLocation.FilesystemPath; x.Reason = reason; } if (foundStudy) { throw x; } CheckForStudyRestore(context.ReadContext, partitionKey, studyInstanceUid, restore); } }
protected bool GetStudyStorageLocation(ServerEntityKey partitionKey, string studyInstanceUid, out StudyStorageLocation location) { using (IReadContext context = PersistentStoreRegistry.GetDefaultStore().OpenReadContext()) { IQueryStudyStorageLocation procedure = context.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters(); parms.ServerPartitionKey = partitionKey; parms.StudyInstanceUid = studyInstanceUid; location = procedure.FindOne(parms); return(location != null); } }
static public IList <StudyStorageLocation> FindStorageLocations(ServerEntityKey partitionKey, string studyInstanceUid) { using (var context = new ServerExecutionContext()) { IQueryStudyStorageLocation locQuery = context.ReadContext.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters locParms = new StudyStorageLocationQueryParameters { StudyInstanceUid = studyInstanceUid, ServerPartitionKey = partitionKey }; IList <StudyStorageLocation> list = locQuery.Find(locParms); return(list); } }
static public IList <StudyStorageLocation> FindStorageLocations( IPersistenceContext context, StudyStorage storage, Predicate <StudyStorageLocation> filter) { IQueryStudyStorageLocation locQuery = context.GetBroker <IQueryStudyStorageLocation>(); StudyStorageLocationQueryParameters locParms = new StudyStorageLocationQueryParameters { StudyInstanceUid = storage.StudyInstanceUid, ServerPartitionKey = storage.ServerPartitionKey }; IList <StudyStorageLocation> list = locQuery.Find(locParms); if (filter != null) { CollectionUtils.Remove(list, filter); } return(list); }
/// <summary> /// Do the restore. /// </summary> /// <param name="queueItem">The queue item to restore.</param> public void Run(RestoreQueue queueItem) { using (RestoreProcessorContext context = new RestoreProcessorContext(queueItem)) { try { // Load up related classes. using (IReadContext readContext = _nasArchive.PersistentStore.OpenReadContext()) { _archiveStudyStorage = ArchiveStudyStorage.Load(readContext, queueItem.ArchiveStudyStorageKey); _serverSyntax = ServerTransferSyntax.Load(readContext, _archiveStudyStorage.ServerTransferSyntaxKey); _syntax = TransferSyntax.GetTransferSyntax(_serverSyntax.Uid); StudyStorageLocationQueryParameters parms = new StudyStorageLocationQueryParameters { StudyStorageKey = queueItem.StudyStorageKey }; IQueryStudyStorageLocation broker = readContext.GetBroker <IQueryStudyStorageLocation>(); _location = broker.FindOne(parms); if (_location == null) { _studyStorage = StudyStorage.Load(readContext, queueItem.StudyStorageKey); if (_studyStorage == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "Unable to find storage location, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "Unable to find storage location, rescheduling request."; _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } } } if (_location == null) { Platform.Log(LogLevel.Info, "Starting restore of nearline study: {0}", _studyStorage.StudyInstanceUid); } else { Platform.Log(LogLevel.Info, "Starting restore of online study: {0}", _location.StudyInstanceUid); } // If restoring a Nearline study, select a filesystem string destinationFolder; if (_location == null) { ServerFilesystemInfo fs = _nasArchive.Selector.SelectFilesystem(); if (fs == null) { DateTime scheduleTime = Platform.Time.AddMinutes(5); Platform.Log(LogLevel.Error, "No writeable filesystem for restore, rescheduling restore request to {0}", scheduleTime); queueItem.FailureDescription = "No writeable filesystem for restore, rescheduling request."; _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime); return; } destinationFolder = Path.Combine(fs.Filesystem.FilesystemPath, _nasArchive.ServerPartition.PartitionFolder); } else { destinationFolder = _location.GetStudyPath(); } // Get the zip file path from the xml data in the ArchiveStudyStorage entry // Also store the "StudyFolder" for use below string studyFolder = String.Empty; string filename = String.Empty; string studyInstanceUid = String.Empty; XmlElement element = _archiveStudyStorage.ArchiveXml.DocumentElement; if (element != null) { foreach (XmlElement node in element.ChildNodes) { if (node.Name.Equals("StudyFolder")) { studyFolder = node.InnerText; } else if (node.Name.Equals("Filename")) { filename = node.InnerText; } else if (node.Name.Equals("Uid")) { studyInstanceUid = node.InnerText; } } } string zipFile = Path.Combine(_nasArchive.NasPath, studyFolder); zipFile = Path.Combine(zipFile, studyInstanceUid); zipFile = Path.Combine(zipFile, filename); // Do a test read of the zip file. If it succeeds, the file is available, if it // fails, we just set back to pending and recheck. try { FileStream stream = File.OpenRead(zipFile); // Read a byte, just in case that makes a difference. stream.ReadByte(); stream.Close(); stream.Dispose(); } catch (Exception ex) { DateTime scheduledTime = Platform.Time.AddSeconds(NasSettings.Default.ReadFailRescheduleDelaySeconds); Platform.Log(LogLevel.Error, ex, "Archive {0} for Study {1} is unreadable, rescheduling restore to {2}", zipFile, _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid, scheduledTime); // Just reschedule in "Restoring" state, the file is unreadable. _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Restoring, scheduledTime); return; } if (_location == null) { RestoreNearlineStudy(queueItem, zipFile, destinationFolder, studyFolder); } else { RestoreOnlineStudy(queueItem, zipFile, destinationFolder); } } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception processing restore request for {0} on archive {1}", _studyStorage == null ? (_location == null ? string.Empty : _location.StudyInstanceUid) : _studyStorage.StudyInstanceUid, _nasArchive.PartitionArchive.Description); queueItem.FailureDescription = e.Message; _nasArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time); } } }