Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        private void ReinventoryFilesystem(Filesystem filesystem)
        {
            ServerPartition partition;

            DirectoryInfo filesystemDir = new DirectoryInfo(filesystem.FilesystemPath);

            foreach (DirectoryInfo partitionDir in filesystemDir.GetDirectories())
            {
                if (GetServerPartition(partitionDir.Name, out partition) == false)
                {
                    continue;
                }

                foreach (DirectoryInfo dateDir in partitionDir.GetDirectories())
                {
                    if (dateDir.FullName.EndsWith("Deleted", StringComparison.InvariantCultureIgnoreCase) ||
                        dateDir.FullName.EndsWith(ServerPlatform.ReconcileStorageFolder, StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }
                    List <FileInfo> fileList;

                    foreach (DirectoryInfo studyDir in dateDir.GetDirectories())
                    {
                        if (studyDir.FullName.EndsWith("Deleted", StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }

                        // Check for Cancel message
                        if (CancelPending)
                        {
                            return;
                        }

                        String studyInstanceUid = studyDir.Name;

                        StudyStorageLocation location;
                        if (GetStudyStorageLocation(partition.Key, studyInstanceUid, out location))
                        {
                            #region Study record exists in db

                            int   integrityQueueCount;
                            int   workQueueCount;
                            Study theStudy = GetStudyAndQueues(location, out integrityQueueCount, out workQueueCount);
                            if (theStudy != null)
                            {
                                continue;
                            }

                            if (integrityQueueCount != 0 && workQueueCount != 0)
                            {
                                continue;
                            }

                            fileList = LoadSopFiles(studyDir, false);

                            if (fileList.Count == 0)
                            {
                                Platform.Log(LogLevel.Warn, "Found empty study folder with StorageLocation, deleteing StorageLocation: {0}\\{1}",
                                             dateDir.Name, studyDir.Name);
                                studyDir.Delete(true);

                                RemoveStudyStorage(location);
                                continue;
                            }

                            // WriteLock the new study storage for study processing
                            if (!location.QueueStudyStateEnum.Equals(QueueStudyStateEnum.ProcessingScheduled))
                            {
                                string failureReason;
                                if (!ServerHelper.LockStudy(location.Key, QueueStudyStateEnum.ProcessingScheduled, out failureReason))
                                {
                                    Platform.Log(LogLevel.Error, "Unable to lock study {0} for Study Processing", location.StudyInstanceUid);
                                }
                            }
                            #endregion
                        }
                        else
                        {
                            #region Directory not in DB,

                            fileList = LoadSopFiles(studyDir, true);

                            if (fileList.Count == 0)
                            {
                                Platform.Log(LogLevel.Warn, "Found empty study folder: {0}\\{1}", dateDir.Name, studyDir.Name);
                                continue;
                            }

                            DicomFile file = LoadFileFromList(fileList);

                            if (file == null)
                            {
                                Platform.Log(LogLevel.Warn, "Found directory with no readable files: {0}\\{1}", dateDir.Name, studyDir.Name);
                                continue;
                            }

                            // Do a second check, using the study instance uid from a file in the directory.
                            // had an issue with trailing periods on uids causing us to not find the
                            // study storage, and insert a new record into the database.
                            studyInstanceUid = file.DataSet[DicomTags.StudyInstanceUid].ToString();
                            if (GetStudyStorageLocation(partition.Key, studyInstanceUid, out location))
                            {
                                continue;
                            }

                            StudyStorage storage;
                            if (GetStudyStorage(partition, studyInstanceUid, out storage))
                            {
                                Platform.Log(LogLevel.Warn, "Study {0} on filesystem partition {1} is offline {2}", studyInstanceUid,
                                             partition.Description, studyDir.ToString());
                                continue;
                            }

                            Platform.Log(LogLevel.Info, "Reinventory inserting study storage location for {0} on partition {1}", studyInstanceUid,
                                         partition.Description);

                            // Insert StudyStorage
                            using (IUpdateContext update = _store.OpenUpdateContext(UpdateContextSyncMode.Flush))
                            {
                                IInsertStudyStorage          studyInsert = update.GetBroker <IInsertStudyStorage>();
                                InsertStudyStorageParameters insertParms = new InsertStudyStorageParameters
                                {
                                    ServerPartitionKey  = partition.GetKey(),
                                    StudyInstanceUid    = studyInstanceUid,
                                    Folder              = dateDir.Name,
                                    FilesystemKey       = filesystem.GetKey(),
                                    QueueStudyStateEnum =
                                        QueueStudyStateEnum.Idle
                                };
                                if (file.TransferSyntax.LosslessCompressed)
                                {
                                    insertParms.TransferSyntaxUid = file.TransferSyntax.UidString;
                                    insertParms.StudyStatusEnum   = StudyStatusEnum.OnlineLossless;
                                }
                                else if (file.TransferSyntax.LossyCompressed)
                                {
                                    insertParms.TransferSyntaxUid = file.TransferSyntax.UidString;
                                    insertParms.StudyStatusEnum   = StudyStatusEnum.OnlineLossy;
                                }
                                else
                                {
                                    insertParms.TransferSyntaxUid = file.TransferSyntax.UidString;
                                    insertParms.StudyStatusEnum   = StudyStatusEnum.Online;
                                }

                                location = studyInsert.FindOne(insertParms);

                                // WriteLock the new study storage for study processing
                                ILockStudy          lockStudy = update.GetBroker <ILockStudy>();
                                LockStudyParameters lockParms = new LockStudyParameters
                                {
                                    StudyStorageKey     = location.Key,
                                    QueueStudyStateEnum =
                                        QueueStudyStateEnum.ProcessingScheduled
                                };
                                if (!lockStudy.Execute(lockParms) || !lockParms.Successful)
                                {
                                    Platform.Log(LogLevel.Error, "Unable to lock study {0} for Study Processing", location.StudyInstanceUid);
                                }

                                update.Commit();
                            }
                            #endregion
                        }

                        string studyXml = location.GetStudyXmlPath();
                        if (File.Exists(studyXml))
                        {
                            FileUtils.Delete(studyXml);
                        }

                        string studyGZipXml = location.GetCompressedStudyXmlPath();
                        if (File.Exists(studyGZipXml))
                        {
                            FileUtils.Delete(studyGZipXml);
                        }


                        foreach (FileInfo sopFile in fileList)
                        {
                            String sopInstanceUid = sopFile.Name.Replace(sopFile.Extension, string.Empty);

                            using (ServerExecutionContext context = new ServerExecutionContext())
                            {
                                // Just use a read context here, in hopes of improving
                                // performance.  Every other place in the code should use
                                // Update contexts when doing transactions.
                                IInsertWorkQueue workQueueInsert =
                                    context.ReadContext.GetBroker <IInsertWorkQueue>();

                                InsertWorkQueueParameters queueInsertParms =
                                    new InsertWorkQueueParameters
                                {
                                    WorkQueueTypeEnum  = WorkQueueTypeEnum.StudyProcess,
                                    StudyStorageKey    = location.GetKey(),
                                    ServerPartitionKey = partition.GetKey(),
                                    SeriesInstanceUid  = sopFile.Directory.Name,
                                    SopInstanceUid     = sopInstanceUid,
                                    ScheduledTime      = Platform.Time
                                };

                                if (workQueueInsert.FindOne(queueInsertParms) == null)
                                {
                                    Platform.Log(LogLevel.Error,
                                                 "Failure attempting to insert SOP Instance into WorkQueue during Reinventory.");
                                }
                            }
                        }
                    }

                    // Cleanup the date directory, if its empty.
                    DirectoryUtility.DeleteIfEmpty(dateDir.FullName);
                }
            }
        }