Ejemplo n.º 1
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);
                }
            }
        }