public void Insert(Guid Guid, Guid ServerPartitionGUID, string StudyInstanceUid, DateTime InsertTime,
                           DateTime LastAccessedTime, bool WriteLock, short ReadLock, short StudyStatusEnum,
                           short QueueStudyStateEnum)
        {
            var item = new StudyStorage();

            item.Guid = Guid;

            item.ServerPartitionGUID = ServerPartitionGUID;

            item.StudyInstanceUid = StudyInstanceUid;

            item.InsertTime = InsertTime;

            item.LastAccessedTime = LastAccessedTime;

            item.WriteLock = WriteLock;

            item.ReadLock = ReadLock;

            item.StudyStatusEnum = StudyStatusEnum;

            item.QueueStudyStateEnum = QueueStudyStateEnum;


            item.Save(UserName);
        }
Exemple #2
0
        public bool CanManipulateSeries(ServerEntityKey studyStorageKey)
        {
            StudyStorage storage = StudyStorage.Load(studyStorageKey);

            return(storage.QueueStudyStateEnum.Equals(QueueStudyStateEnum.Idle));
        }
Exemple #3
0
        public StudyStorage GetStudyStorage(Study study)
        {
            Platform.CheckForNullReference(study, "Study");

            return(StudyStorage.Load(study.StudyStorageKey));
        }
 private void LoadEntities()
 {
     _storage = StudyStorage.Load(_oldStudyLocation.Key);
     _study   = _storage.LoadStudy(UpdateContext);
 }
        private static bool GetStudyStorage(ServerPartition partition, string studyInstanceUid, out StudyStorage storage)
        {
            using (var context = new ServerExecutionContext())
            {
                storage = StudyStorage.Load(context.ReadContext, partition.Key, studyInstanceUid);
                if (storage != null)
                {
                    return(true);
                }

                return(false);
            }
        }
Exemple #6
0
 /// <summary>
 /// Finds all <see cref="StudyHistory"/> records for the specified <see cref="StudyStorage"/>.
 /// </summary>
 /// <param name="studyStorage"></param>
 /// <returns></returns>
 static public IList <StudyHistory> FindStudyHistories(StudyStorage studyStorage)
 {
     return(FindStudyHistories(studyStorage, null));
 }
        /// <summary>
        /// Returns all authority groups (data-access or not)
        /// that have access to the study not through direct data access assignment but through other means, such as administrative tokens
        /// </summary>
        /// <param name="studyStorage"></param>
        /// <returns></returns>
        public IList <AuthorityGroupStudyAccessInfo> ListAuthorityGroupsForStudyViaToken(StudyStorage studyStorage)
        {
            // list all Authority Groups (data or non data-access) with permission to access all studies on the same partition
            var adapter = new ServerPartitionDataAdapter();
            IList <AuthorityGroupDetail> groupWithAccessToAllStudies;

            adapter.GetAuthorityGroupsForPartition(studyStorage.ServerPartitionKey, false, out groupWithAccessToAllStudies);

            // Convert into AuthorityGroupStudyAccessInfo objects for rendering
            var result = new List <AuthorityGroupStudyAccessInfo>();

            foreach (var groupDetail in groupWithAccessToAllStudies)
            {
                result.Add(new AuthorityGroupStudyAccessInfo(groupDetail));
            }


            return(result);
        }
Exemple #8
0
        /// <summary>
        /// Constructs an instance of <see cref="WorkQueueSummary"/> based on a <see cref="WorkQueue"/> object.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        /// <remark>
        ///
        /// </remark>
        private WorkQueueSummary CreateWorkQueueSummary(WorkQueue item)
        {
            WorkQueueSummary summary = new WorkQueueSummary
            {
                TheWorkQueueItem = item,
                ThePartition     = Partition
            };

            // Fetch the patient info:
            StudyStorageAdaptor ssAdaptor = new StudyStorageAdaptor();
            StudyStorage        storages  = ssAdaptor.Get(item.StudyStorageKey);

            if (storages == null)
            {
                summary.PatientId    = "N/A";
                summary.PatientsName = "N/A";
                return(summary);
            }
            StudyAdaptor        studyAdaptor  = new StudyAdaptor();
            StudySelectCriteria studycriteria = new StudySelectCriteria();

            studycriteria.StudyInstanceUid.EqualTo(storages.StudyInstanceUid);
            studycriteria.ServerPartitionKey.EqualTo(item.ServerPartitionKey);
            IList <Study> studyList = studyAdaptor.Get(studycriteria);

            if (studyList == null || studyList.Count == 0)
            {
                summary.PatientId    = "N/A";
                summary.PatientsName = "N/A";
            }
            else
            {
                summary.PatientId    = studyList[0].PatientId;
                summary.PatientsName = studyList[0].PatientsName;
            }

            if (item.WorkQueueTypeEnum == WorkQueueTypeEnum.WebMoveStudy ||
                item.WorkQueueTypeEnum == WorkQueueTypeEnum.AutoRoute)
            {
                DeviceDataAdapter deviceAdaptor = new DeviceDataAdapter();
                Device            dest          = deviceAdaptor.Get(item.DeviceKey);

                summary.Notes = String.Format("Destination AE : {0}", dest.AeTitle);

                if (item.FailureDescription != null)
                {
                    summary.FullDescription = String.Format("{0}, {1}", summary.Notes, item.FailureDescription);                       //Set the FullDescription for the Tooltip in the GUI
                    summary.Notes           = summary.FullDescription.Length > 60
                                                ? summary.FullDescription.Substring(0, 60)
                                                : summary.FullDescription;
                }
            }
            else if (item.FailureDescription != null)
            {
                // This used to only be shown when the status was "Failed" for a
                // queue entry.  We now show it any time there's
                if (item.FailureDescription.Length > 60)
                {
                    summary.Notes           = item.FailureDescription.Substring(0, 60);
                    summary.Notes          += " ...";
                    summary.FullDescription = item.FailureDescription;                  //Set the FullDescription for the Tooltip in the GUI
                }
                else
                {
                    summary.Notes = item.FailureDescription;
                }
            }

            summary.RequiresAttention = item.WorkQueueStatusEnum.Equals(WorkQueueStatusEnum.Failed) || !ServerPlatform.IsActiveWorkQueue(item);
            return(summary);
        }
Exemple #9
0
        private void LoadMergedStudyEntities()
        {
            StudyStorage storage = StudyStorage.Load(_destinationStudyStorage.Key);

            _destinationStudyStorage = StudyStorageLocation.FindStorageLocations(storage)[0];
        }
Exemple #10
0
        /// <summary>
        /// Do the restore.
        /// </summary>
        /// <param name="queueItem">The queue item to restore.</param>
        public void Run(RestoreQueue queueItem)
        {
            using (var context = new RestoreProcessorContext(queueItem))
            {
                try
                {
                    // Load up related classes.
                    using (IReadContext readContext = _hsmArchive.PersistentStore.OpenReadContext())
                    {
                        _archiveStudyStorage = ArchiveStudyStorage.Load(readContext, queueItem.ArchiveStudyStorageKey);
                        _serverSyntax        = ServerTransferSyntax.Load(readContext, _archiveStudyStorage.ServerTransferSyntaxKey);
                        _syntax = TransferSyntax.GetTransferSyntax(_serverSyntax.Uid);

                        var parms = new StudyStorageLocationQueryParameters
                        {
                            StudyStorageKey = queueItem.StudyStorageKey
                        };
                        var 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.";
                                _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Pending, scheduleTime);
                                return;
                            }
                        }
                    }

                    if (_location == null)
                    {
                        Platform.Log(LogLevel.Info, "Starting restore of nearline study: {0}",
                                     _studyStorage.StudyInstanceUid);

                        // Get the zip file path from the xml data in the ArchiveStudyStorage entry
                        // Also store the "StudyFolder" for use below
                        string studyFolder;
                        string zipFile = GetZipFileName(out studyFolder);

                        // 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.
                        if (!CanReadZip(zipFile, queueItem))
                        {
                            return;
                        }

                        RestoreNearlineStudy(queueItem, zipFile, studyFolder);
                    }
                    else
                    {
                        Platform.Log(LogLevel.Info, "Starting restore of online study: {0}", _location.StudyInstanceUid);

                        // Get the zip file path from the xml data in the ArchiveStudyStorage entry
                        // Also store the "StudyFolder" for use below
                        string studyFolder;
                        string zipFile = GetZipFileName(out studyFolder);

                        // 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.
                        if (!CanReadZip(zipFile, queueItem))
                        {
                            return;
                        }

                        RestoreOnlineStudy(queueItem, zipFile, _location.GetStudyPath());
                    }
                }
                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,
                                 _hsmArchive.PartitionArchive.Description);
                    queueItem.FailureDescription = e.Message;
                    _hsmArchive.UpdateRestoreQueue(queueItem, RestoreQueueStatusEnum.Failed, Platform.Time);
                }
            }
        }
        private AutoReconcilerResult MergeImage(StudyReconcileAction action, DicomFile file, StudyHistory lastHistory)
        {
            string originalSeriesUid = file.DataSet[DicomTags.SeriesInstanceUid].ToString();
            string originalSopUid    = file.DataSet[DicomTags.SopInstanceUid].ToString();

            AutoReconcilerResult preProcessingResult = null;
            StudyStorageLocation destStudy;
            UidMapper            uidMapper = null;

            if (lastHistory.DestStudyStorageKey != null)
            {
                StudyStorage destinationStudy = StudyStorage.Load(lastHistory.DestStudyStorageKey);

                //Load the destination.  An exception will be thrown if any issues are encountered.
                FilesystemMonitor.Instance.GetWritableStudyStorageLocation(destinationStudy.ServerPartitionKey,
                                                                           destinationStudy.StudyInstanceUid,
                                                                           StudyRestore.True, StudyCache.True,
                                                                           out destStudy);

                EnsureStudyCanBeUpdated(destStudy);

                bool belongsToAnotherStudy = !destStudy.Equals(StorageLocation);

                ImageUpdateCommandBuilder           commandBuilder = new ImageUpdateCommandBuilder();
                IList <BaseImageLevelUpdateCommand> commands       = commandBuilder.BuildCommands <StudyMatchingMap>(destStudy);
                if (belongsToAnotherStudy)
                {
                    Platform.Log(LogLevel.Info, "AUTO-RECONCILE: Move SOP {0} to Study {1}, A#: {2}, Patient {3}", originalSopUid, destStudy.StudyInstanceUid, destStudy.Study.AccessionNumber, destStudy.Study.PatientsName);

                    // Load the Uid Map, either from cache or from disk
                    if (!_uidMapCache.TryGetValue(destStudy.Key, out uidMapper))
                    {
                        UidMapXml mapXml = new UidMapXml();
                        mapXml.Load(destStudy);
                        uidMapper = new UidMapper(mapXml);

                        _uidMapCache.Add(destStudy.Key, uidMapper);
                    }

                    try
                    {
                        commands.Add(GetUidMappingCommand(StorageLocation, destStudy, uidMapper, originalSopUid, originalSeriesUid));
                    }
                    catch (InstanceAlreadyExistsException ex)
                    {
                        Platform.Log(LogLevel.Info, "An instance already exists with the SOP Instance Uid {0}", ex.SopInstanceUid);
                        preProcessingResult = new AutoReconcilerResult(StudyReconcileAction.Discard)
                        {
                            DiscardImage = true
                        };

                        return(preProcessingResult);
                    }
                }


                preProcessingResult = new AutoReconcilerResult(action)
                {
                    Changes = GetUpdateList(file, commands)
                };

                UpdateImage(file, commands);

                // First, must update the map
                if (uidMapper != null && uidMapper.Dirty)
                {
                    UpdateUidMap(destStudy, uidMapper);
                }

                if (belongsToAnotherStudy)
                {
                    SopInstanceImporterContext importContext = new SopInstanceImporterContext(_contextID, file.SourceApplicationEntityTitle, destStudy.ServerPartition);
                    SopInstanceImporter        importer      = new SopInstanceImporter(importContext);
                    DicomProcessingResult      result        = importer.Import(file);

                    if (!result.Successful)
                    {
                        throw new ApplicationException(result.ErrorMessage);
                    }
                }
            }
            return(preProcessingResult);
        }
        /// <summary>
        /// Returns an instance of <see cref="StudySummary"/> based on a <see cref="Study"/> object.
        /// </summary>
        /// <param name="study"></param>
        /// <param name="read"></param>
        /// <returns></returns>
        /// <remark>
        ///
        /// </remark>
        static public StudySummary CreateStudySummary(IPersistenceContext read, Study study)
        {
            if (study == null)
            {
                return(null);
            }

            var studySummary = new StudySummary();
            var controller   = new StudyController();

            studySummary.Key             = study.GetKey();
            studySummary.AccessionNumber = study.AccessionNumber;
            studySummary.NumberOfStudyRelatedInstances = study.NumberOfStudyRelatedInstances;
            studySummary.NumberOfStudyRelatedSeries    = study.NumberOfStudyRelatedSeries;
            studySummary.PatientId               = study.PatientId;
            studySummary.PatientsName            = study.PatientsName;
            studySummary.StudyDate               = study.StudyDate;
            studySummary.StudyInstanceUid        = study.StudyInstanceUid;
            studySummary.StudyDescription        = study.StudyDescription;
            studySummary.ModalitiesInStudy       = controller.GetModalitiesInStudy(read, study);
            studySummary.ReferringPhysiciansName = study.ReferringPhysiciansName;
            studySummary.ResponsibleOrganization = study.ResponsibleOrganization;
            studySummary.ResponsiblePerson       = study.ResponsiblePerson;
            studySummary.StudyTime               = study.StudyTime;
            studySummary.StudyId  = study.StudyId;
            studySummary.TheStudy = study;

            studySummary.ThePartition = ServerPartitionMonitor.Instance.FindPartition(study.ServerPartitionKey) ??
                                        ServerPartition.Load(read, study.ServerPartitionKey);

            studySummary.ReferringPhysiciansName = study.ReferringPhysiciansName;
            studySummary.TheStudyStorage         = StudyStorage.Load(read, study.StudyStorageKey);
            studySummary.StudyStatusEnum         = studySummary.TheStudyStorage.StudyStatusEnum;
            studySummary.QueueStudyStateEnum     = studySummary.TheStudyStorage.QueueStudyStateEnum;

            studySummary.TheArchiveLocation = controller.GetFirstArchiveStudyStorage(read, studySummary.TheStudyStorage.Key);

            studySummary.IsArchiving = controller.GetArchiveQueueCount(study) > 0;

            studySummary.IsProcessing = studySummary.TheStudyStorage.WriteLock;

            // the study is considered "locked" if it's being processed or some action which requires the lock has been scheduled
            // No additional action should be allowed on the study until everything is completed.
            studySummary.IsLocked = studySummary.IsProcessing ||
                                    (studySummary.TheStudyStorage.QueueStudyStateEnum != QueueStudyStateEnum.Idle);

            if (controller.GetStudyIntegrityQueueCount(studySummary.TheStudyStorage.Key) > 0)
            {
                studySummary.IsReconcileRequired = true;
            }

            studySummary.HasPendingExternalEdit = controller.GetCountPendingExternalEditWorkQueueItems(study) > 0;
            if (studySummary.HasPendingExternalEdit)
            {
                studySummary.HasPendingWorkQueueItems = true;
            }
            else
            {
                studySummary.HasPendingWorkQueueItems = controller.GetCountPendingWorkQueueItems(study) > 0;
            }

            var ep = new StudySummaryAssemblerExtensionPoint();

            foreach (IStudySummaryAssembler assemblerPlugin in ep.CreateExtensions())
            {
                assemblerPlugin.PopulateStudy(studySummary, study);
            }

            return(studySummary);
        }