static public FilesystemStudyStorage Insert(IUpdateContext update, FilesystemStudyStorage entity) { var broker = update.GetBroker<IFilesystemStudyStorageEntityBroker>(); var updateColumns = new FilesystemStudyStorageUpdateColumns(); updateColumns.StudyStorageKey = entity.StudyStorageKey; updateColumns.FilesystemKey = entity.FilesystemKey; updateColumns.ServerTransferSyntaxKey = entity.ServerTransferSyntaxKey; updateColumns.StudyFolder = entity.StudyFolder; FilesystemStudyStorage newEntity = broker.Insert(updateColumns); return newEntity; }
protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext) { // Update StudyStatusEnum in the StudyStorageTable IStudyStorageEntityBroker studyStorageUpdate = updateContext.GetBroker<IStudyStorageEntityBroker>(); StudyStorageUpdateColumns studyStorageUpdateColumns = new StudyStorageUpdateColumns(); studyStorageUpdateColumns.StudyStatusEnum = _newStatus; studyStorageUpdate.Update(_location.Key, studyStorageUpdateColumns); // Update ServerTransferSyntaxGUID in FilesystemStudyStorage IFilesystemStudyStorageEntityBroker filesystemUpdate = updateContext.GetBroker<IFilesystemStudyStorageEntityBroker>(); FilesystemStudyStorageUpdateColumns filesystemUpdateColumns = new FilesystemStudyStorageUpdateColumns(); filesystemUpdateColumns.ServerTransferSyntaxKey = _newSyntax.Key; filesystemUpdate.Update(_location.FilesystemStudyStorageKey, filesystemUpdateColumns); }
/// <summary> /// Traverse the filesystem directories for studies to rebuild the XML for. /// </summary> /// <param name="filesystem"></param> private void TraverseFilesystemStudies(Filesystem filesystem) { List<StudyStorageLocation> lockFailures = new List<StudyStorageLocation>(); 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") || dateDir.FullName.EndsWith(ServerPlatform.ReconcileStorageFolder)) continue; foreach (DirectoryInfo studyDir in dateDir.GetDirectories()) { // Check for Cancel message if (CancelPending) return; String studyInstanceUid = studyDir.Name; StudyStorageLocation location; try { FilesystemMonitor.Instance.GetWritableStudyStorageLocation(partition.Key, studyInstanceUid, StudyRestore.False, StudyCache.False, out location); } catch (StudyNotFoundException) { List<FileInfo> 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 (!studyInstanceUid.Equals(studyDir.Name)) try { FilesystemMonitor.Instance.GetWritableStudyStorageLocation(partition.Key, studyInstanceUid, StudyRestore.False, StudyCache.False, out location); } catch (Exception e) { Platform.Log(LogLevel.Warn, "Study {0} on filesystem partition {1} not found {2}: {3}", studyInstanceUid, partition.Description, studyDir.ToString(), e.Message); continue; } else { Platform.Log(LogLevel.Warn, "Study {0} on filesystem partition {1} not found {2}", studyInstanceUid, partition.Description, studyDir.ToString()); continue; } } catch (Exception e) { Platform.Log(LogLevel.Warn, "Study {0} on filesystem partition {1} not found {2}: {3}", studyInstanceUid, partition.Description, studyDir.ToString(), e.Message); continue; } // Location has been loaded, make sure its on the same filesystem if (!location.FilesystemKey.Equals(filesystem.Key)) { Platform.Log(LogLevel.Warn, "Study {0} on filesystem in directory: {1} is stored in different directory in the database: {2}", studyInstanceUid, studyDir.ToString(), location.GetStudyPath()); try { // Here due to defect #9673, attempting to cleanup errors from this ticket. if (Directory.Exists(location.GetStudyPath())) { if (File.Exists(location.GetStudyXmlPath())) { Platform.Log(LogLevel.Warn, "Deleting study {0}'s local directory. The database location has valid study: {1}", studyInstanceUid, studyDir.FullName); Directory.Delete(studyDir.FullName,true); continue; } Platform.Log(LogLevel.Warn, "Deleting study {0} directory stored in database, it does not have a study xml file: {1}", studyInstanceUid, location.GetStudyPath()); // Delete the Database's location, and we'll just adjust the database to point to the current directory Directory.Delete(location.GetStudyPath(),true); } using ( var readContext = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext( UpdateContextSyncMode.Flush)) { var update = new FilesystemStudyStorageUpdateColumns { FilesystemKey = filesystem.Key }; var broker = readContext.GetBroker<IFilesystemStudyStorageEntityBroker>(); broker.Update(location.FilesystemStudyStorageKey, update); readContext.Commit(); } Platform.Log(LogLevel.Warn, "Updated Study {0} FilesystemStudyStorage to point to the current filesystem.", studyInstanceUid); FilesystemMonitor.Instance.GetWritableStudyStorageLocation(partition.Key, studyInstanceUid, StudyRestore.False, StudyCache.False, out location); } catch (Exception x) { Platform.Log(LogLevel.Error, x, "Unexpected error attempting to update storage location for study: {0}", studyInstanceUid); } } try { if (!location.AcquireWriteLock()) { Platform.Log(LogLevel.Warn, "Unable to lock study: {0}, delaying rebuild", location.StudyInstanceUid); lockFailures.Add(location); continue; } var rebuilder = new StudyXmlRebuilder(location); rebuilder.RebuildXml(); location.ReleaseWriteLock(); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception when rebuilding study xml for study: {0}", location.StudyInstanceUid); lockFailures.Add(location); } } // Cleanup the parent date directory, if its empty DirectoryUtility.DeleteIfEmpty(dateDir.FullName); } } // Re-do all studies that failed locks one time foreach (StudyStorageLocation location in lockFailures) { try { if (!location.AcquireWriteLock()) { Platform.Log(LogLevel.Warn, "Unable to lock study: {0}, skipping rebuild", location.StudyInstanceUid); continue; } StudyXmlRebuilder rebuilder = new StudyXmlRebuilder(location); rebuilder.RebuildXml(); location.ReleaseWriteLock(); } catch (Exception e) { Platform.Log(LogLevel.Error, e, "Unexpected exception on retry when rebuilding study xml for study: {0}", location.StudyInstanceUid); } } }
/// <summary> /// Updates the status of a study to a new status /// </summary> protected virtual void UpdateStudyStatus(StudyStorageLocation theStudyStorage, StudyStatusEnum theStatus, TransferSyntax theSyntax) { DBUpdateTime.Add( delegate { using ( IUpdateContext updateContext = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { // Select the Server Transfer Syntax ServerTransferSyntaxSelectCriteria syntaxCriteria = new ServerTransferSyntaxSelectCriteria(); IServerTransferSyntaxEntityBroker syntaxBroker = updateContext.GetBroker<IServerTransferSyntaxEntityBroker>(); syntaxCriteria.Uid.EqualTo(theSyntax.UidString); ServerTransferSyntax serverSyntax = syntaxBroker.FindOne(syntaxCriteria); if (serverSyntax == null) { Platform.Log(LogLevel.Error, "Unable to load ServerTransferSyntax for {0}. Unable to update study status.", theSyntax.Name); return; } // Get the FilesystemStudyStorage update broker ready IFilesystemStudyStorageEntityBroker filesystemQueueBroker = updateContext.GetBroker<IFilesystemStudyStorageEntityBroker>(); FilesystemStudyStorageUpdateColumns filesystemQueueUpdate = new FilesystemStudyStorageUpdateColumns { ServerTransferSyntaxKey = serverSyntax.GetKey() }; FilesystemStudyStorageSelectCriteria filesystemQueueCriteria = new FilesystemStudyStorageSelectCriteria(); filesystemQueueCriteria.StudyStorageKey.EqualTo(theStudyStorage.GetKey()); // Get the StudyStorage update broker ready IStudyStorageEntityBroker studyStorageBroker = updateContext.GetBroker<IStudyStorageEntityBroker>(); StudyStorageUpdateColumns studyStorageUpdate = new StudyStorageUpdateColumns { StudyStatusEnum = theStatus, LastAccessedTime = Platform.Time }; if (!filesystemQueueBroker.Update(filesystemQueueCriteria,filesystemQueueUpdate)) { Platform.Log(LogLevel.Error, "Unable to update FilesystemQueue row: Study {0}, Server Entity {1}", theStudyStorage.StudyInstanceUid, theStudyStorage.ServerPartitionKey); } else if (!studyStorageBroker.Update(theStudyStorage.GetKey(),studyStorageUpdate)) { Platform.Log(LogLevel.Error, "Unable to update StudyStorage row: Study {0}, Server Entity {1}", theStudyStorage.StudyInstanceUid, theStudyStorage.ServerPartitionKey); } else updateContext.Commit(); } } ); }
protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext) { // Check if the File is the same syntax as the TransferSyntax fileSyntax = _file.TransferSyntax; TransferSyntax dbSyntax = TransferSyntax.GetTransferSyntax(_location.TransferSyntaxUid); // Check if the syntaxes match the location if ((!fileSyntax.Encapsulated && !dbSyntax.Encapsulated) || (fileSyntax.LosslessCompressed && dbSyntax.LosslessCompressed) || (fileSyntax.LossyCompressed && dbSyntax.LossyCompressed)) { // no changes necessary, just return; return; } // Select the Server Transfer Syntax var syntaxCriteria = new ServerTransferSyntaxSelectCriteria(); var syntaxBroker = updateContext.GetBroker<IServerTransferSyntaxEntityBroker>(); syntaxCriteria.Uid.EqualTo(fileSyntax.UidString); ServerTransferSyntax serverSyntax = syntaxBroker.FindOne(syntaxCriteria); if (serverSyntax == null) { Platform.Log(LogLevel.Error, "Unable to load ServerTransferSyntax for {0}. Unable to update study status.", fileSyntax.Name); return; } // Get the FilesystemStudyStorage update broker ready var filesystemStudyStorageEntityBroker = updateContext.GetBroker<IFilesystemStudyStorageEntityBroker>(); var filesystemStorageUpdate = new FilesystemStudyStorageUpdateColumns(); var filesystemStorageCritiera = new FilesystemStudyStorageSelectCriteria(); filesystemStorageUpdate.ServerTransferSyntaxKey = serverSyntax.Key; filesystemStorageCritiera.StudyStorageKey.EqualTo(_location.Key); // Save a StudyHistory record for the compression that occurred. StudyHistoryHelper.CreateStudyHistoryRecord(updateContext, _location, _location, StudyHistoryTypeEnum.SopCompress, null, new CompressionStudyHistory { TimeStamp = Platform.Time, OriginalTransferSyntaxUid = dbSyntax.UidString, FinalTransferSyntaxUid = fileSyntax.UidString }); // Get the StudyStorage update broker ready var studyStorageBroker = updateContext.GetBroker<IStudyStorageEntityBroker>(); var studyStorageUpdate = new StudyStorageUpdateColumns(); StudyStatusEnum statusEnum = _location.StudyStatusEnum; if (fileSyntax.LossyCompressed) studyStorageUpdate.StudyStatusEnum = statusEnum = StudyStatusEnum.OnlineLossy; else if (fileSyntax.LosslessCompressed) studyStorageUpdate.StudyStatusEnum = statusEnum = StudyStatusEnum.OnlineLossless; studyStorageUpdate.LastAccessedTime = Platform.Time; if (!filesystemStudyStorageEntityBroker.Update(filesystemStorageCritiera, filesystemStorageUpdate)) { Platform.Log(LogLevel.Error, "Unable to update FilesystemQueue row: Study {0}, Server Entity {1}", _location.StudyInstanceUid, _location.ServerPartitionKey); } else if (!studyStorageBroker.Update(_location.GetKey(), studyStorageUpdate)) { Platform.Log(LogLevel.Error, "Unable to update StudyStorage row: Study {0}, Server Entity {1}", _location.StudyInstanceUid, _location.ServerPartitionKey); } else { // Update the location, so the next time we come in here, we don't try and update the database // for another sop in the study. _location.StudyStatusEnum = statusEnum; _location.TransferSyntaxUid = fileSyntax.UidString; _location.ServerTransferSyntaxKey = serverSyntax.Key; } }