Esempio n. 1
0
        /// <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]);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        /// <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);
            }
        }
Esempio n. 5
0
        /// <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);
            }
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
 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);
     }
 }
Esempio n. 8
0
        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);
                }
            }
        }