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); } }
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); }
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}"); }
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 { } }