public async Task OnCStoreRequestAsync_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <AsyncDicomCStoreProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                DicomCStoreResponse             response = null;
                DicomRequest.OnTimeoutEventArgs timeout  = null;
                var request = new DicomCStoreRequest(TestData.Resolve("10200904.dcm"))
                {
                    OnResponseReceived = (req, res) => response = res,
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.NotNull(response);
                Assert.Equal(DicomStatus.Success, response.Status);
                Assert.Null(timeout);
            }
        }
示例#2
0
        public DicomCStoreResponse OnCStoreRequest(DicomCStoreRequest request)
        {
            Listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Received CStore Request: " + request.SOPInstanceUID));
            DicomCStoreResponse response;

            try
            {
                response = new DicomCStoreResponse(request, DicomStatus.Success);
                OnEndProcessingCStoreRequest(request, response);
            }
            catch (Exception e)
            {
                Listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, "Failed CStore: " + request.SOPInstanceUID, e));
                response = new DicomCStoreResponse(request, DicomStatus.ProcessingFailure);
            }
            Listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Sending CStore Response: " + response.Status + " from AET: " + CalledAE + " to AET:" + CallingAE));
            return(response);
        }
        public async Task SendAsync_WithGenericStreamException_ShouldNotLoopInfinitely()
        {
            var port   = Ports.GetNext();
            var logger = _logger.IncludePrefix("UnitTest");

            DicomCStoreResponse response1 = null, response2 = null, response3 = null;

            DicomRequest.OnTimeoutEventArgs timeout1 = null, timeout2 = null, timeout3 = null;
            using (CreateServer <InMemoryDicomCStoreProvider>(port))
            {
                var request1HasArrived = false;
                var clientFactory      = CreateClientFactory(new ConfigurableNetworkManager(() =>
                {
                    if (request1HasArrived)
                    {
                        throw new Exception("Request 1 has arrived, we can no longer write to this stream!");
                    }
                }));
                var client = clientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name).WithMinimumLevel(LogLevel.Debug);

                // Ensure requests are handled sequentially
                client.NegotiateAsyncOps(1, 1);

                // Size = 5 192 KB, one PDU = 16 KB, so this will result in 325 PDUs
                // If stream timeout = 1500ms, then total time to send will be 325 * 1500 = 487.5 seconds
                var request1 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) =>
                    {
                        request1HasArrived = true;
                        response1          = res;
                    },
                    OnTimeout = (sender, args) => timeout1 = args
                };
                var request2 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response2 = res,
                    OnTimeout          = (sender, args) => timeout2 = args
                };
                var request3 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response3 = res,
                    OnTimeout          = (sender, args) => timeout3 = args
                };

                await client.AddRequestsAsync(new[] { request1, request2, request3 }).ConfigureAwait(false);

                using var cancellation = new CancellationTokenSource(TimeSpan.FromSeconds(30));

                Exception exception = null;
                try
                {
                    await client.SendAsync(cancellation.Token, DicomClientCancellationMode.ImmediatelyAbortAssociation).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    exception = e;
                }

                Assert.NotNull(exception);
                Assert.False(cancellation.IsCancellationRequested, "The DicomClient had to be cancelled, this indicates it was stuck in an infinite loop");
            }

            Assert.NotNull(response1);
            Assert.Null(response2);
            Assert.Null(response3);
            Assert.Null(timeout1);
            Assert.Null(timeout2);
            Assert.Null(timeout3);
        }
示例#4
0
 private static void OnStoreResponseReceivedFromRemoteHost(DicomCStoreRequest request, DicomCStoreResponse response)
 {
     LogToDebugConsole("DICOM Store request was received by remote host for storage...");
     LogToDebugConsole($"DICOM Store request was received by remote host for SOP instance transmitted for storage:{request.SOPInstanceUID}");
     LogToDebugConsole($"Store operation response status returned was:{response.Status}");
 }
示例#5
0
 public void OnCStoreRequestComplete(DicomCStoreRequest request, DicomCStoreResponse response)
 {
     _logger.Log(LogLevel.Information, $"MessageID: {response.RequestMessageID} status: {response.Status.Code} description: {response.Status.Description} comment: {response.Status.ErrorComment} state: {response.Status.State}");
 }
        public async Task SendAsync_WithSocketException_ShouldNotLoopInfinitely()
        {
            var port   = Ports.GetNext();
            var logger = _logger.IncludePrefix("UnitTest");

            IDicomServer        server = null;
            DicomCStoreResponse response1 = null, response2 = null, response3 = null;

            DicomRequest.OnTimeoutEventArgs timeout1 = null, timeout2 = null, timeout3 = null;
            using (CreateServer <InMemoryDicomCStoreProvider>(port))
            {
                var client = CreateClient(port);

                var request1HasArrived = false;
                client.NetworkManager = new ConfigurableNetworkManager(() =>
                {
                    if (request1HasArrived)
                    {
                        throw new IOException("Request 1 has arrived, we can no longer write to this stream!",
                                              new SocketException());
                    }
                });

                // Ensure requests are handled sequentially
                client.NegotiateAsyncOps(1, 1);

                // Size = 5 192 KB, one PDU = 16 KB, so this will result in 325 PDUs
                // If stream timeout = 1500ms, then total time to send will be 325 * 1500 = 487.5 seconds
                var request1 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) =>
                    {
                        request1HasArrived = true;
                        response1          = res;
                    },
                    OnTimeout = (sender, args) => timeout1 = args
                };
                var request2 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response2 = res,
                    OnTimeout          = (sender, args) => timeout2 = args
                };
                var request3 = new DicomCStoreRequest(@"./Test Data/10200904.dcm")
                {
                    OnResponseReceived = (req, res) => response3 = res,
                    OnTimeout          = (sender, args) => timeout3 = args
                };

                await client.AddRequestsAsync(request1, request2, request3).ConfigureAwait(false);

                using (var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                {
                    Exception exception = null;
                    try
                    {
                        await client.SendAsync(cancellation.Token, DicomClientCancellationMode.ImmediatelyAbortAssociation).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        exception = e;
                    }

                    Assert.NotNull(exception);

                    Assert.False(cancellation.IsCancellationRequested);
                }
            }

            Assert.NotNull(response1);
            Assert.Null(response2);
            Assert.Null(response3);
            Assert.Null(timeout1);
            Assert.Null(timeout2);
            Assert.Null(timeout3);
        }
        /// 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
            {
            }
        }