protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext) { var insert = updateContext.GetBroker <IInsertWorkQueue>(); var parms = new InsertWorkQueueParameters { WorkQueueTypeEnum = WorkQueueTypeEnum.StudyProcess, StudyStorageKey = _storageLocation.GetKey(), ServerPartitionKey = _storageLocation.ServerPartitionKey, SeriesInstanceUid = _message.DataSet[DicomTags.SeriesInstanceUid].GetString(0, String.Empty), SopInstanceUid = _message.DataSet[DicomTags.SopInstanceUid].GetString(0, String.Empty), ScheduledTime = Platform.Time, WorkQueueGroupID = _uidGroupId }; if (_duplicate) { parms.Duplicate = _duplicate; parms.Extension = _extension; parms.UidGroupID = _uidGroupId; } _insertedWorkQueue = insert.FindOne(parms); if (_insertedWorkQueue == null) { throw new ApplicationException("UpdateWorkQueueCommand failed"); } }
static public void Insert(StudyStorageLocation storageLocation, string studyInstanceUId, string seriesInstanceUid, string sopInstanceUid, DicomPixelData pixeldata) { lock (_cache) { string key = String.Format("{0}/{1}/{2}/{3}", storageLocation.GetKey().Key, studyInstanceUId, seriesInstanceUid, sopInstanceUid); _cache.Add(key, pixeldata, null, Cache.NoAbsoluteExpiration, _retentionTime, CacheItemPriority.Normal, null); } }
private void CreateSubCommands() { _archiveXml = new XmlDocument(); _studyXml = _storageLocation.LoadStudyXml(); string studyFolder = _storageLocation.GetStudyPath(); // Create the study date folder _zipFilename = Path.Combine(_hsmPath, _storageLocation.StudyFolder); AddSubCommand(new CreateDirectoryCommand(_zipFilename)); // Create a folder for the study _zipFilename = Path.Combine(_zipFilename, _storageLocation.StudyInstanceUid); AddSubCommand(new CreateDirectoryCommand(_zipFilename)); // Save the archive data in the study folder, based on a filename with a date / time stamp string filename = String.Format("{0}.zip", Platform.Time.ToString("yyyy-MM-dd-HHmm")); _zipFilename = Path.Combine(_zipFilename, filename); // Create the Xml data to store in the ArchiveStudyStorage table telling // where the archived study is located. XmlElement hsmArchiveElement = _archiveXml.CreateElement("HsmArchive"); _archiveXml.AppendChild(hsmArchiveElement); XmlElement studyFolderElement = _archiveXml.CreateElement("StudyFolder"); hsmArchiveElement.AppendChild(studyFolderElement); studyFolderElement.InnerText = _storageLocation.StudyFolder; XmlElement filenameElement = _archiveXml.CreateElement("Filename"); hsmArchiveElement.AppendChild(filenameElement); filenameElement.InnerText = filename; XmlElement studyInstanceUidElement = _archiveXml.CreateElement("Uid"); hsmArchiveElement.AppendChild(studyInstanceUidElement); studyInstanceUidElement.InnerText = _storageLocation.StudyInstanceUid; // Create the Zip file var zipStudyCommand = new CreateStudyZipCommand(_zipFilename, _studyXml, studyFolder, _tempPath) { ForceCompress = this.ForceCompress }; zipStudyCommand.ProgressUpdated += (s, e) => EventsHelper.Fire(this.ProgressUpdated, this, e); AddSubCommand(zipStudyCommand); // Update the database. AddSubCommand(new InsertArchiveStudyStorageCommand(_storageLocation.GetKey(), _archive.GetKey(), _storageLocation.ServerTransferSyntaxKey, _archiveXml)); }
public static StudyHistory CreateStudyHistoryRecord(IUpdateContext updateContext, StudyStorageLocation primaryStudyLocation, StudyStorageLocation secondaryStudyLocation, StudyHistoryTypeEnum type, object entryInfo, object changeLog) { var columns = new StudyHistoryUpdateColumns { InsertTime = Platform.Time, StudyHistoryTypeEnum = type, StudyStorageKey = primaryStudyLocation.GetKey(), DestStudyStorageKey = secondaryStudyLocation != null ? secondaryStudyLocation.GetKey() : primaryStudyLocation.GetKey(), StudyData = XmlUtils.SerializeAsXmlDoc(entryInfo) ?? new XmlDocument(), ChangeDescription = XmlUtils.SerializeAsXmlDoc(changeLog) ?? new XmlDocument() }; var broker = updateContext.GetBroker <IStudyHistoryEntityBroker>(); return(broker.Insert(columns)); }
protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext) { var deleteInstanceBroker = updateContext.GetBroker <IDeleteInstance>(); var parameters = new DeleteInstanceParameters { StudyStorageKey = _studyLocation.GetKey(), SeriesInstanceUid = _seriesInstanceUid, SOPInstanceUid = _sopInstanceUid }; if (!deleteInstanceBroker.Execute(parameters)) { throw new ApplicationException("Unable to update instance count in db"); } }
protected override void OnExecute(CommandProcessor theProcessor, IUpdateContext updateContext) { var insert = updateContext.GetBroker <IInsertWorkQueue>(); var parms = new InsertWorkQueueParameters { WorkQueueTypeEnum = WorkQueueTypeEnum.StudyProcess, StudyStorageKey = _storageLocation.GetKey(), ServerPartitionKey = _storageLocation.ServerPartitionKey, SeriesInstanceUid = _message.DataSet[DicomTags.SeriesInstanceUid].GetString(0, String.Empty), SopInstanceUid = _message.DataSet[DicomTags.SopInstanceUid].GetString(0, String.Empty), ScheduledTime = Platform.Time, }; if (_priority != null) { parms.WorkQueuePriorityEnum = _priority; } if (_data != null) { parms.WorkQueueData = ImageServerSerializer.SerializeWorkQueueDataToXmlDocument(_data); } if (_request != null) { parms.ExternalRequestQueueKey = _request.Key; } if (_uidData != null) { parms.WorkQueueUidData = _uidData; parms.Extension = _uidData.Extension; parms.UidGroupID = _uidData.GroupId; parms.WorkQueueGroupID = _uidData.GroupId; } if (_duplicate) { parms.Duplicate = _duplicate; } _insertedWorkQueue = insert.FindOne(parms); if (_insertedWorkQueue == null) { throw new ApplicationException("UpdateWorkQueueCommand failed"); } }
static public DicomPixelData Find(StudyStorageLocation storageLocation, string studyInstanceUId, string seriesInstanceUid, string sopInstanceUid ) { lock (_cache) { string key = String.Format("{0}/{1}/{2}/{3}", storageLocation.GetKey().Key, studyInstanceUId, seriesInstanceUid, sopInstanceUid); object cachedPD = _cache.Get(key); if (cachedPD != null) { //Platform.Log(LogLevel.Info, "Pixel data found in cache"); return cachedPD as DicomPixelData; } else return null; } }
static public DicomPixelData Find(StudyStorageLocation storageLocation, string studyInstanceUId, string seriesInstanceUid, string sopInstanceUid) { lock (_cache) { string key = String.Format("{0}/{1}/{2}/{3}", storageLocation.GetKey().Key, studyInstanceUId, seriesInstanceUid, sopInstanceUid); object cachedPD = _cache.Get(key); if (cachedPD != null) { //Platform.Log(LogLevel.Info, "Pixel data found in cache"); return(cachedPD as DicomPixelData); } else { return(null); } } }
public void OnStudyDeleting() { if (!Enabled) { return; } StudyStorageLocation storage = _context.StorageLocation; IList <ArchiveStudyStorage> archives = StudyStorageLocation.GetArchiveLocations(storage.GetKey()); if (archives != null && archives.Count > 0) { _archives = new DeletedStudyArchiveInfoCollection(); foreach (ArchiveStudyStorage archive in archives) { DeletedStudyArchiveInfo archiveInfo = new DeletedStudyArchiveInfo(); archiveInfo.ArchiveTime = archive.ArchiveTime; archiveInfo.ArchiveXml = archive.ArchiveXml; archiveInfo.PartitionArchiveRef = PartitionArchive.Load(archive.PartitionArchiveKey).GetKey().Key; archiveInfo.TransferSyntaxUid = archive.ServerTransferSyntax.Uid; _archives.Add(archiveInfo); } } // only backup if study is manually deleted if (_context.WorkQueueItem.WorkQueueTypeEnum == WorkQueueTypeEnum.WebDeleteStudy) { using (var processor = new ServerCommandProcessor("Backup deleted study")) { string path = _context.Filesystem.ResolveAbsolutePath(BackupSubPath); Platform.Log(LogLevel.Info, "Saving a copy of the study to {0}...", path); var mkdir = new CreateDirectoryCommand(path); processor.AddCommand(mkdir); var zip = new ZipStudyFolderCommand(storage.GetStudyPath(), BackupFullPath); processor.AddCommand(zip); if (!processor.Execute()) { throw new ApplicationException(String.Format("Unable to backup study: {0}", processor.FailureReason)); } } } }
static public DicomPixelData Find(StudyStorageLocation storageLocation, string studyInstanceUId, string seriesInstanceUid, string sopInstanceUid) { string key = String.Format("{0}/{1}/{2}/{3}", storageLocation.GetKey().Key, studyInstanceUId, seriesInstanceUid, sopInstanceUid); return(_cache.Get(key) as DicomPixelData); }
/// <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(); } } ); }
/// <summary> /// Archive the specified <see cref="ArchiveQueue"/> item. /// </summary> /// <param name="queueItem">The ArchiveQueue item to archive.</param> public void Run(ArchiveQueue queueItem) { using (ArchiveProcessorContext executionContext = new ArchiveProcessorContext(queueItem)) { try { if (!GetStudyStorageLocation(queueItem)) { Platform.Log(LogLevel.Error, "Unable to find readable study storage location for archival queue request {0}. Delaying request.", queueItem.Key); queueItem.FailureDescription = "Unable to find readable study storage location for archival queue request."; _hsmArchive.UpdateArchiveQueue(queueItem, ArchiveQueueStatusEnum.Pending, Platform.Time.AddMinutes(2)); return; } // First, check to see if we can lock the study, if not just reschedule the queue entry. if (!_storageLocation.QueueStudyStateEnum.Equals(QueueStudyStateEnum.Idle)) { Platform.Log(LogLevel.Info, "Study {0} on partition {1} is currently locked, delaying archival.", _storageLocation.StudyInstanceUid, _hsmArchive.ServerPartition.Description); queueItem.FailureDescription = "Study is currently locked, delaying archival."; _hsmArchive.UpdateArchiveQueue(queueItem, ArchiveQueueStatusEnum.Pending, Platform.Time.AddMinutes(2)); return; } StudyIntegrityValidator validator = new StudyIntegrityValidator(); validator.ValidateStudyState("Archive", _storageLocation, StudyIntegrityValidationModes.Default); using (IUpdateContext update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { ILockStudy studyLock = update.GetBroker <ILockStudy>(); LockStudyParameters parms = new LockStudyParameters { StudyStorageKey = queueItem.StudyStorageKey, QueueStudyStateEnum = QueueStudyStateEnum.ArchiveScheduled }; bool retVal = studyLock.Execute(parms); if (!parms.Successful || !retVal) { Platform.Log(LogLevel.Info, "Study {0} on partition {1} failed to lock, delaying archival.", _storageLocation.StudyInstanceUid, _hsmArchive.ServerPartition.Description); queueItem.FailureDescription = "Study failed to lock, delaying archival."; _hsmArchive.UpdateArchiveQueue(queueItem, ArchiveQueueStatusEnum.Pending, Platform.Time.AddMinutes(2)); return; } update.Commit(); } string studyXmlFile = _storageLocation.GetStudyXmlPath(); // Load the study Xml file, this is used to generate the list of dicom files to archive. LoadStudyXml(studyXmlFile); DicomFile file = LoadFileFromStudyXml(); string patientsName = file.DataSet[DicomTags.PatientsName].GetString(0, string.Empty); string patientId = file.DataSet[DicomTags.PatientId].GetString(0, string.Empty); string accessionNumber = file.DataSet[DicomTags.AccessionNumber].GetString(0, string.Empty); Platform.Log(LogLevel.Info, "Starting archival of study {0} for Patient {1} (PatientId:{2} A#:{3}) on Partition {4} on archive {5}", _storageLocation.StudyInstanceUid, patientsName, patientId, accessionNumber, _hsmArchive.ServerPartition.Description, _hsmArchive.PartitionArchive.Description); // Use the command processor to do the archival. using (ServerCommandProcessor commandProcessor = new ServerCommandProcessor("Archive")) { var archiveStudyCmd = new ArchiveStudyCommand(_storageLocation, _hsmArchive.HsmPath, executionContext.TempDirectory, _hsmArchive.PartitionArchive) { ForceCompress = HsmSettings.Default.CompressZipFiles }; commandProcessor.AddCommand(archiveStudyCmd); commandProcessor.AddCommand(new UpdateArchiveQueueItemCommand(queueItem.GetKey(), _storageLocation.GetKey(), ArchiveQueueStatusEnum.Completed)); StudyRulesEngine studyEngine = new StudyRulesEngine(_storageLocation, _hsmArchive.ServerPartition, _studyXml); studyEngine.Apply(ServerRuleApplyTimeEnum.StudyArchived, commandProcessor); if (!commandProcessor.Execute()) { Platform.Log(LogLevel.Error, "Unexpected failure archiving study ({0}) to archive {1}: {2}, zip filename: {3}", _storageLocation.StudyInstanceUid, _hsmArchive.PartitionArchive.Description, commandProcessor.FailureReason, archiveStudyCmd.OutputZipFilePath); queueItem.FailureDescription = commandProcessor.FailureReason; _hsmArchive.UpdateArchiveQueue(queueItem, ArchiveQueueStatusEnum.Failed, Platform.Time); } else { Platform.Log(LogLevel.Info, "Successfully archived study {0} on {1} to zip {2}", _storageLocation.StudyInstanceUid, _hsmArchive.PartitionArchive.Description, archiveStudyCmd.OutputZipFilePath); } // Log the current FilesystemQueue settings _storageLocation.LogFilesystemQueue(); } } catch (StudyIntegrityValidationFailure ex) { StringBuilder error = new StringBuilder(); error.AppendLine(String.Format("Partition : {0}", ex.ValidationStudyInfo.ServerAE)); error.AppendLine(String.Format("Patient : {0}", ex.ValidationStudyInfo.PatientsName)); error.AppendLine(String.Format("Study Uid : {0}", ex.ValidationStudyInfo.StudyInstaneUid)); error.AppendLine(String.Format("Accession# : {0}", ex.ValidationStudyInfo.AccessionNumber)); error.AppendLine(String.Format("Study Date : {0}", ex.ValidationStudyInfo.StudyDate)); queueItem.FailureDescription = error.ToString(); _hsmArchive.UpdateArchiveQueue(queueItem, ArchiveQueueStatusEnum.Failed, Platform.Time); } catch (Exception e) { String msg = String.Format("Unexpected exception archiving study: {0} on {1}: {2}", _storageLocation.StudyInstanceUid, _hsmArchive.PartitionArchive.Description, e.Message); Platform.Log(LogLevel.Error, e, msg); queueItem.FailureDescription = msg; _hsmArchive.UpdateArchiveQueue(queueItem, ArchiveQueueStatusEnum.Failed, Platform.Time); } finally { // Unlock the Queue Entry using (IUpdateContext update = PersistentStoreRegistry.GetDefaultStore().OpenUpdateContext(UpdateContextSyncMode.Flush)) { ILockStudy studyLock = update.GetBroker <ILockStudy>(); LockStudyParameters parms = new LockStudyParameters { StudyStorageKey = queueItem.StudyStorageKey, QueueStudyStateEnum = QueueStudyStateEnum.Idle }; bool retVal = studyLock.Execute(parms); if (!parms.Successful || !retVal) { Platform.Log(LogLevel.Info, "Study {0} on partition {1} is failed to unlock.", _storageLocation.StudyInstanceUid, _hsmArchive.ServerPartition.Description); } update.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); // 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; } }
public static StudyHistory CreateStudyHistoryRecord(IUpdateContext updateContext, StudyStorageLocation primaryStudyLocation, StudyStorageLocation secondaryStudyLocation, StudyHistoryTypeEnum type, object entryInfo, object changeLog) { StudyHistoryUpdateColumns columns = new StudyHistoryUpdateColumns { InsertTime = Platform.Time, StudyHistoryTypeEnum = type, StudyStorageKey = primaryStudyLocation.GetKey(), DestStudyStorageKey = secondaryStudyLocation != null ? secondaryStudyLocation.GetKey() : primaryStudyLocation.GetKey(), StudyData = XmlUtils.SerializeAsXmlDoc(entryInfo) ?? new XmlDocument(), ChangeDescription = XmlUtils.SerializeAsXmlDoc(changeLog) ?? new XmlDocument() }; IStudyHistoryEntityBroker broker = updateContext.GetBroker<IStudyHistoryEntityBroker>(); return broker.Insert(columns); }
static public DicomPixelData Find(StudyStorageLocation storageLocation, string studyInstanceUId, string seriesInstanceUid, string sopInstanceUid ) { string key = String.Format("{0}/{1}/{2}/{3}", storageLocation.GetKey().Key, studyInstanceUId, seriesInstanceUid, sopInstanceUid); return _cache.Get(key) as DicomPixelData; }