示例#1
0
        /// <summary>
        /// Create Duplicate SIQ Entry
        /// </summary>
        /// <param name="file"></param>
        /// <param name="location"></param>
        /// <param name="sourcePath"></param>
        /// <param name="queue"></param>
        /// <param name="uid"></param>
        /// <param name="data"></param>
        public static void CreateDuplicateSIQEntry(DicomFile file, StudyStorageLocation location, string sourcePath,
                                                   WorkQueue queue, WorkQueueUid uid, StudyProcessWorkQueueData data)
        {
            Platform.Log(LogLevel.Info, "Creating Work Queue Entry for duplicate...");
            String uidGroup = queue.GroupID ?? queue.GetKey().Key.ToString();

            using (var commandProcessor = new ServerCommandProcessor("Insert Work Queue entry for duplicate"))
            {
                commandProcessor.AddCommand(new FileDeleteCommand(sourcePath, true));

                var sopProcessingContext     = new SopInstanceProcessorContext(commandProcessor, location, uidGroup);
                DicomProcessingResult result = Process(sopProcessingContext, file, data);
                if (!result.Successful)
                {
                    FailUid(uid, true);
                    return;
                }

                commandProcessor.AddCommand(new DeleteWorkQueueUidCommand(uid));

                if (!commandProcessor.Execute())
                {
                    Platform.Log(LogLevel.Error, "Unexpected error when creating duplicate study integrity queue entry: {0}",
                                 commandProcessor.FailureReason);
                    FailUid(uid, true);
                }
            }
        }
示例#2
0
        /// <summary>
        /// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
        /// </summary>
        /// <param name="context">The processing context</param>
        /// <param name="file">The file</param>
        /// <param name="data">The data</param>
        /// <param name="duplicate">How the processor should handle the duplicate</param>
        public static void ProcessStoredDuplicate(SopInstanceProcessorContext context,
                                                  DicomFile file,
                                                  StudyProcessWorkQueueData data,
                                                  DuplicateProcessingEnum duplicate)
        {
            SaveDuplicate(context, file);
            var uidData = new WorkQueueUidData
            {
                Extension           = ServerPlatform.DuplicateFileExtension,
                GroupId             = context.Group,
                DuplicateProcessing = duplicate
            };

            if (context.Request != null)
            {
                uidData.OperationToken = context.Request.OperationToken;
            }

            context.CommandProcessor.AddCommand(
                new UpdateWorkQueueCommand(file, context.StudyLocation, true, data, uidData, context.Request));
        }
示例#3
0
        /// <summary>
        /// Process the duplicate with the supplied <see cref="DuplicateProcessingEnum"/>
        /// </summary>
        /// <param name="context">The processing context</param>
        /// <param name="message">A subset of the message stored in <paramref name="sourceFilename"/></param>
        /// <param name="sourceFilename">The location of the filename that is a duplicate</param>
        /// <param name="data">The data</param>
        /// <param name="duplicate">How the processor should handle the duplicate</param>
        public static void ProcessStoredDuplicateFile(SopInstanceProcessorContext context,
                                                      string sourceFilename,
                                                      DicomMessageBase message,
                                                      StudyProcessWorkQueueData data,
                                                      DuplicateProcessingEnum duplicate)
        {
            SaveDuplicateFile(context, message.DataSet[DicomTags.SopInstanceUid].ToString(), sourceFilename);
            var uidData = new WorkQueueUidData
            {
                Extension           = ServerPlatform.DuplicateFileExtension,
                GroupId             = context.Group,
                DuplicateProcessing = duplicate
            };

            if (context.Request != null)
            {
                uidData.OperationToken = context.Request.OperationToken;
            }

            context.CommandProcessor.AddCommand(
                new UpdateWorkQueueCommand(message, context.StudyLocation, true, data, uidData, context.Request));
        }
示例#4
0
        private static void SaveDuplicateFile(SopInstanceProcessorContext context, string sopInstanceUid, string sourceFilename)
        {
            String path = Path.Combine(context.StudyLocation.FilesystemPath, context.StudyLocation.PartitionFolder);

            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.Group /* the AE title + timestamp */);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.StudyLocation.StudyInstanceUid);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path  = Path.Combine(path, sopInstanceUid);
            path += "." + ServerPlatform.DuplicateFileExtension;

            context.CommandProcessor.AddCommand(new RenameFileCommand(sourceFilename, path, true));

            Platform.Log(ServerPlatform.InstanceLogLevel, "Duplicate ==> {0}", path);
        }
示例#5
0
        private static void SaveDuplicate(SopInstanceProcessorContext context, DicomFile file)
        {
            String sopUid = file.DataSet[DicomTags.SopInstanceUid].ToString();

            String path = Path.Combine(context.StudyLocation.FilesystemPath, context.StudyLocation.PartitionFolder);

            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, ServerPlatform.ReconcileStorageFolder);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.Group /* the AE title + timestamp */);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path = Path.Combine(path, context.StudyLocation.StudyInstanceUid);
            context.CommandProcessor.AddCommand(new CreateDirectoryCommand(path));

            path  = Path.Combine(path, sopUid);
            path += "." + ServerPlatform.DuplicateFileExtension;

            context.CommandProcessor.AddCommand(new SaveDicomFileCommand(path, file, true));

            Platform.Log(ServerPlatform.InstanceLogLevel, "Duplicate ==> {0}", path);
        }
示例#6
0
        /// <summary>
        /// Inserts the duplicate DICOM file into the <see cref="WorkQueue"/> for processing (if applicable).
        /// </summary>
        /// <param name="context">The processing context.</param>
        /// <param name="file">The duplicate DICOM file being processed.</param>
        /// <param name="data">Extra data to insert for the WorkQueue item.</param>
        /// <param name="sourceFilename">Optional source filename already saved to disk to import.</param>
        /// <returns>A <see cref="DicomProcessingResult"/> that contains the result of the processing.</returns>
        /// <remarks>
        /// This method inserts a <see cref="CommandBase"/> into <paramref name="context.CommandProcessor"/>.
        /// The outcome of the operation depends on the <see cref="DuplicateSopPolicyEnum"/> of the <see cref="ServerPartition"/>.
        /// If it is set to <see cref="DuplicateSopPolicyEnum.CompareDuplicates"/>, the duplicate file will be
        /// inserted into the <see cref="WorkQueue"/> for processing.
        /// </remarks>
        public static DicomProcessingResult Process(SopInstanceProcessorContext context, DicomMessageBase file,
                                                    StudyProcessWorkQueueData data, string sourceFilename = null)
        {
            Platform.CheckForNullReference(file, "file");
            Platform.CheckForNullReference(context, "context");
            Platform.CheckMemberIsSet(context.Group, "parameters.Group");
            Platform.CheckMemberIsSet(context.CommandProcessor, "parameters.CommandProcessor");
            Platform.CheckMemberIsSet(context.StudyLocation, "parameters.StudyLocation");
            if (string.IsNullOrEmpty(sourceFilename))
            {
                Platform.CheckForNullReference(file as DicomFile, "file");
            }

            var result = new DicomProcessingResult
            {
                DicomStatus       = DicomStatuses.Success,
                Successful        = true,
                StudyInstanceUid  = file.DataSet[DicomTags.StudyInstanceUid].GetString(0, string.Empty),
                SeriesInstanceUid = file.DataSet[DicomTags.SeriesInstanceUid].GetString(0, string.Empty),
                SopInstanceUid    = file.DataSet[DicomTags.SopInstanceUid].GetString(0, string.Empty),
                SopClassUid       = file.DataSet[DicomTags.SopClassUid].GetString(0, string.Empty),
                AccessionNumber   = file.DataSet[DicomTags.AccessionNumber].GetString(0, string.Empty)
            };

            string failureMessage;

            if (context.DuplicateProcessing.HasValue && context.DuplicateProcessing.Value.Equals(DuplicateProcessingEnum.Reject))
            {
                failureMessage = String.Format("Duplicate SOP Instance received, rejecting {0}", result.SopInstanceUid);
                Platform.Log(LogLevel.Info, failureMessage);
                result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
                return(result);
            }

            if (SopClassIsReport(result.SopClassUid) && context.StudyLocation.ServerPartition.AcceptLatestReport)
            {
                Platform.Log(LogLevel.Info, "Duplicate Report received, overwriting {0}", result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteReport);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteReport);
                }

                return(result);
            }

            if (DuplicatePolicy.IsParitionDuplicatePolicyOverridden(context.StudyLocation))
            {
                // Note: this is a special case where we need to temporarily override the duplicate policy for a particular study
                // so that SIQ entry can be processed (#10569). This should only happen once in a blue moon.

                Platform.Log(LogLevel.Warn,
                             "Duplicate instance received for study {0} on Partition {1}. Duplicate policy overridden in app config. Will overwrite {2}",
                             result.StudyInstanceUid, context.StudyLocation.ServerPartition.AeTitle, result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteSop);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteSop);
                }
                return(result);
            }

            if (context.DuplicateProcessing.HasValue)
            {
                Platform.Log(LogLevel.Info, context.DuplicateProcessing.Value.Equals(DuplicateProcessingEnum.Compare)
                                                                    ? "Duplicate SOP Instance received, comparing {0}"
                                                                    : "Duplicate SOP Instance received, overwriting {0}", result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, context.DuplicateProcessing.Value);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, context.DuplicateProcessing.Value);
                }

                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.AcceptLatest))
            {
                Platform.Log(LogLevel.Info, "Duplicate SOP Instance received, overwriting {0}", result.SopInstanceUid);
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.OverwriteSopAndUpdateDatabase);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.OverwriteSopAndUpdateDatabase);
                }
                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.SendSuccess))
            {
                Platform.Log(LogLevel.Info, "Duplicate SOP Instance received, sending success response {0}", result.SopInstanceUid);
                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.RejectDuplicates))
            {
                failureMessage = String.Format("Duplicate SOP Instance received, rejecting {0}", result.SopInstanceUid);
                Platform.Log(LogLevel.Info, failureMessage);
                result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
                return(result);
            }

            if (context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum.Equals(DuplicateSopPolicyEnum.CompareDuplicates))
            {
                if (string.IsNullOrEmpty(sourceFilename))
                {
                    ProcessStoredDuplicate(context, file as DicomFile, data, DuplicateProcessingEnum.Compare);
                }
                else
                {
                    ProcessStoredDuplicateFile(context, sourceFilename, file, data, DuplicateProcessingEnum.Compare);
                }
            }
            else
            {
                failureMessage = String.Format("Duplicate SOP Instance received. Unsupported duplicate policy {0}.",
                                               context.StudyLocation.ServerPartition.DuplicateSopPolicyEnum);
                result.SetError(DicomStatuses.DuplicateSOPInstance, failureMessage);
                return(result);
            }

            return(result);
        }