public async Task <Priority> CheckAndDelayOnWaitConditions(RoutedItem ri)
        {
            RoutedItemEx routedItem = (RoutedItemEx)ri;
            var          taskInfo   = $"task: {routedItem.TaskID}";

            /*
             * check and delay on wait conditions
             * DICOM TAG (0000,0700)
             * LOW = 0002H
             * MEDIUM = 0000H
             * HIGH = 0001H
             */
            //Engage: Waits get engaged when DICOM Priority Tag detected, and get disengaged when done
            ushort priority = 3;

            try
            {
                if (routedItem.sourceDicomFile != null)
                {
                    DicomDataset dataSet = routedItem.sourceDicomFile.Dataset;

                    string uuid = null;
                    try
                    {
                        if (dataSet.Contains(DicomTag.StudyInstanceUID))
                        {
                            uuid = dataSet.GetValue <string>(DicomTag.StudyInstanceUID, 0);
                        }
                    }
                    catch (DicomDataException e)
                    {
                        _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no StudyInstanceUID field. {e.Message} {e.StackTrace}");
                    }

                    Profile currentProfile = _profileStorage.Current;

                    try
                    {
                        if (dataSet.Contains(DicomTag.Priority))
                        {
                            priority = dataSet.GetValue <ushort>(DicomTag.Priority, 0);
                        }
                        else
                        {
                            _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no priority field.");
                        }
                    }
                    catch (DicomDataException e)
                    {
                        _logger.Log(LogLevel.Debug, $"{taskInfo} {uuid} has no priority field. {e.Message} {e.StackTrace}");
                    }

                    if (priority < 3)
                    {
                        _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} has priority {priority}.");
                        if (priority.Equals(0x01))
                        {
                            currentProfile.highWait = true;
                            _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} with high priority detected.  Setting highWait flag.");
                        }

                        if (priority.Equals(0x00))
                        {
                            currentProfile.mediumWait = true;
                            _logger.Log(LogLevel.Information, $"{taskInfo} {uuid} with medium priority detected.  Setting highWait flag.");
                        }
                    }

                    //Wait on Condition:
                    if (currentProfile.highWait || currentProfile.mediumWait)
                    { //something important is in mid transfer so check and wait if med or low
                        if (priority < 3 || priority.Equals(0x02))
                        {
                            //low or no priority is subject to both highWait and mediumWait conditions
                            if (currentProfile.highWait && !priority.Equals(0x01))
                            {
                                _logger.Log(LogLevel.Information, $"{taskInfo} highWait causing {currentProfile.highWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}.");
                                await Task.Delay(currentProfile.highWaitDelay, _taskManager.cts.Token).ConfigureAwait(false);
                            }
                            if (currentProfile.mediumWait && !priority.Equals(0x00) && !priority.Equals(0x01))
                            {
                                _logger.Log(LogLevel.Information, $"{taskInfo} mediumWait causing {currentProfile.mediumWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}.");
                                await Task.Delay(currentProfile.mediumWaitDelay, _taskManager.cts.Token).ConfigureAwait(false);
                            }
                        }
                        else if (priority.Equals(0x00))
                        {
                            //medium priority is subject to only highWait conditions
                            if (currentProfile.highWait)
                            {
                                _logger.Log(LogLevel.Information, $"{taskInfo} highWait causing {currentProfile.highWaitDelay}ms delay for DICOM {uuid} in thread:{System.Threading.Thread.CurrentThread}.");
                                await Task.Delay(currentProfile.highWaitDelay, _taskManager.cts.Token).ConfigureAwait(false);
                            }
                        }
                    }
                }
            }
            catch (TaskCanceledException)
            {
                _logger.Log(LogLevel.Information, $"Task was canceled.");
            }
            catch (Exception e)
            {
                _logger.LogFullException(e);
            }
            return(_util.GetPriority(priority));
        }
Пример #2
0
        /// Responds to a cstore request, which kicks off a StreamToRules task
        public DicomCStoreResponse OnCStoreRequest(DicomCStoreRequest request)
        {
            var taskID = _taskManager.NewTaskID();

            var taskInfo =
                $"task: {taskID} messageID: {request.MessageID} connection: {((DICOMConnection)(base.UserState)).name}";

            try
            {
                var fromConnection = _connectionFinder.GetDicomConnectionToLocalAETitle(_profileStorage.Current, Association.CalledAE);

                if (fromConnection == null)
                {
                    //We have an inbound Association.CalledAE that we aren't configured for
                    logger.Log(LogLevel.Warning, $"{taskInfo} There is no connection defined where the LocalAETitle matches the Association.CalledAE: {Association.CalledAE}");
                    return(new DicomCStoreResponse(request, DicomStatus.ProcessingFailure));
                }

                logger.Log(LogLevel.Information, $"{taskInfo} CStoreRequest from {fromConnection.name}");

                var conn = ((DICOMConnection)(base.UserState));
                // var dir = profile.tempPath + Path.DirectorySeparatorChar + ((DICOMConnection)(base.UserState)).name + Path.DirectorySeparatorChar + "toRules";
                // Directory.CreateDirectory(dir);
                // var filename = dir + Path.DirectorySeparatorChar + System.Guid.NewGuid();
                // LifeImageLite.Logger.logger.Log(TraceEventType.Verbose, $"{taskInfo} Moving from {request.File.File.Name} to {filename}");
                // request.File.File.Move(dstFileName: filename);
                RoutedItem routedItem = new RoutedItem(
                    fromConnection: fromConnection.name,
                    sourceFileName: request.File.File.Name,
                    taskID: taskID)
                {
                    type = RoutedItem.Type.DICOM
                };

                request.Dataset.TryGetValue <string>(DicomTag.PatientID, 0, out routedItem.PatientID);
                request.Dataset.TryGetValue <string>(DicomTag.AccessionNumber, 0, out routedItem.AccessionNumber);
                request.Dataset.TryGetValue <string>(DicomTag.StudyInstanceUID, 0, out routedItem.Study);
                request.Dataset.TryGetValue <string>(DicomTag.StudyID, 0, out routedItem.StudyID);

                foreach (var item in request.Command)
                {
                    logger.Log(LogLevel.Debug, $"Command tag: {item.Tag} value: {item.ValueRepresentation}");
                }

                routedItem.id =
                    $"PID:{routedItem.PatientID}, AN:{routedItem.AccessionNumber}"; // , UID:{routedItem.Study}";

                //profile.rules.SendToRules(routedItem).Wait();
                routedItem.priority = _util.GetPriority((ushort)request.Priority);

                _routedItemManager.Init(routedItem);
                _routedItemManager.Enqueue(conn, conn.toRules, nameof(conn.toRules), copy: true);
                DicomStatus status = DicomStatus.Success;

                DicomCStoreResponse response = new DicomCStoreResponse(request, status)
                {
                    //Dataset = request.Dataset
                };
                response.Command.AddOrUpdate(DicomTag.AffectedSOPInstanceUID,
                                             request.Dataset.GetValue <string>(DicomTag.SOPInstanceUID, 0));
                response.Command.AddOrUpdate(DicomTag.AffectedSOPClassUID,
                                             request.Dataset.GetValue <string>(DicomTag.SOPClassUID, 0));
                return(response);
            }
            catch (Exception e)
            {
                logger.Log(LogLevel.Critical, $"{taskInfo} {e.Message} {e.StackTrace}");

                if (e.InnerException != null)
                {
                    logger.Log(LogLevel.Critical, $"Inner Exception: {e.InnerException}");
                }

                request.Dataset.AddOrUpdate(DicomTag.AffectedSOPInstanceUID,
                                            request.Dataset.GetValue <string>(DicomTag.SOPInstanceUID, 0));
                return(new DicomCStoreResponse(request,
                                               new DicomStatus(DicomStatus.ProcessingFailure,
                                                               $"CStore Response Exception: {e.Message} {e.StackTrace}"))); //out of resources not much flexibility here
            }
            finally
            {
            }
        }