Пример #1
0
        private string GenerateJobName(string pipelineName, InstanceStorageInfo instance)
        {
            Guard.Against.NullOrWhiteSpace(pipelineName, nameof(pipelineName));
            Guard.Against.Null(instance, nameof(instance));

            return($"{instance.CalledAeTitle}-{pipelineName}-{DateTime.UtcNow:yyyyMMddHHmmss}");
        }
        public void NewInstanceStored(InstanceStorageInfo instance)
        {
            Guard.Against.Null(instance, nameof(instance));

            _logger.Log(LogLevel.Information, "Notifying {0} observers of new instance stored {1}", _observers.Count, instance.SopInstanceUid);

            var observerHandledInstances = 0;

            foreach (var observer in _observers)
            {
                try
                {
                    observer.OnNext(instance);
                    observerHandledInstances++;
                }
                catch (InstanceNotSupportedException)
                {
                    //no op
                }
                catch (ArgumentNullException ex)
                {
                    _logger.Log(LogLevel.Error, ex, "Received a null instance");
                }
            }

            if (observerHandledInstances == 0)
            {
                _logger.Log(LogLevel.Warning, "Instance not supported by any of the configured AE Titles, notifying Storage Space Reclaimer Service.");
                _cleanupQueue.QueueInstance(instance);
            }
        }
Пример #3
0
        public void HandleCStoreRequest(DicomCStoreRequest request, string calledAeTitle, uint associationId)
        {
            Guard.Against.Null(request, nameof(request));

            if (!_aeTitleManagers.ContainsKey(calledAeTitle))
            {
                throw new ArgumentException($"Called AE Title '{calledAeTitle}' is not configured");
            }

            if (!_storageInfoProvider.HasSpaceAvailableToStore)
            {
                throw new InsufficientStorageAvailableException($"Insufficient storage available.  Available storage space: {_storageInfoProvider.AvailableFreeSpace:D}");
            }

            _logger.Log(LogLevel.Information, $"Preparing to save instance received for {calledAeTitle} in {_aeTitleManagers[calledAeTitle].Value.AeStorageRootFullPath}.");

            var instanceStorage = InstanceStorageInfo.CreateInstanceStorageInfo(request, _aeTitleManagers[calledAeTitle].Value.AeStorageRootFullPath, calledAeTitle, associationId);

            using (_logger.BeginScope("SOPInstanceUID={0}", instanceStorage.SopInstanceUid))
            {
                _logger.Log(LogLevel.Information, "Patient ID: {PatientId}", instanceStorage.PatientId);
                _logger.Log(LogLevel.Information, "Study Instance UID: {StudyInstanceUid}", instanceStorage.StudyInstanceUid);
                _logger.Log(LogLevel.Information, "Series Instance UID: {SeriesInstanceUid}", instanceStorage.SeriesInstanceUid);
                _logger.Log(LogLevel.Information, "Storage File Path: {InstanceStorageFullPath}", instanceStorage.InstanceStorageFullPath);

                _aeTitleManagers[calledAeTitle].Value.Save(request, instanceStorage);
                _logger.Log(LogLevel.Debug, $"Instance saved with handler {instanceStorage.InstanceStorageFullPath}");
            }
        }
Пример #4
0
        private string GenerateJobName(string pipelineName, InstanceStorageInfo instance)
        {
            Guard.Against.NullOrWhiteSpace(pipelineName, nameof(pipelineName));
            Guard.Against.Null(instance, nameof(instance));

            return($"{instance.CalledAeTitle}-{pipelineName}-{instance.PatientId}");
        }
        public void ShallSaveAndNotify()
        {
            _dicomToolkit.Setup(p => p.Save(It.IsAny <DicomFile>(), It.IsAny <string>()));
            _notificationService.Setup(p => p.NewInstanceStored(It.IsAny <InstanceStorageInfo>()));

            var config = new ClaraApplicationEntity();

            config.AeTitle   = "my-aet";
            config.Processor = "Nvidia.Clara.DicomAdapter.Test.Unit.MockJobProcessor, Nvidia.Clara.Dicom.Test.Unit";
            var handler = new ApplicationEntityHandler(_serviceProvider, config, _rootStoragePath, _cancellationTokenSource.Token, _fileSystem);

            var request  = GenerateRequest();
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _rootStoragePath, config.AeTitle, _fileSystem);

            handler.Save(request, instance);
            _fileSystem.File.Create(instance.InstanceStorageFullPath);
            handler.Save(request, instance);

            _logger.VerifyLogging(LogLevel.Error, Times.Never());
            _logger.VerifyLogging("Instance already exists, skipping.", LogLevel.Information, Times.Once());
            _logger.VerifyLogging("Instance saved successfully.", LogLevel.Debug, Times.Once());
            _logger.VerifyLogging("Instance stored and notified successfully.", LogLevel.Information, Times.Once());

            _dicomToolkit.Verify(p => p.Save(It.IsAny <DicomFile>(), It.IsAny <string>()), Times.Exactly(1));
            _notificationService.Verify(p => p.NewInstanceStored(instance), Times.Once());
        }
Пример #6
0
        public void CreateWithValidData()
        {
            var expectedAeStoragePath           = Path.Combine(_storageRoot, "MyAeTitle");
            var expectedAeAssocationStoragePath = Path.Combine(expectedAeStoragePath, "1", "dcm");
            var expectedPatientStoragePath      = Path.Combine(expectedAeAssocationStoragePath, "PID");
            var expectedSeriesStoragePath       = Path.Combine(expectedPatientStoragePath, Path.Combine(_studyInstanceUid, _seriesInstanceUid));
            var expectedInstanceStoragePath     = Path.Combine(expectedSeriesStoragePath, $"{_sopInstanceUid}.dcm");

            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(
                _request,
                expectedAeStoragePath,
                "MyAeTitle",
                1,
                _fileSystem);

            Assert.Equal("1.2.3", instance.SopClassUid);
            Assert.Equal("PID", instance.PatientId);
            Assert.Equal(_studyInstanceUid, instance.StudyInstanceUid);
            Assert.Equal(_seriesInstanceUid, instance.SeriesInstanceUid);
            Assert.Equal(_sopInstanceUid, instance.SopInstanceUid);
            Assert.Equal("MyAeTitle", instance.CalledAeTitle);
            Assert.Equal(expectedAeAssocationStoragePath, instance.AeStoragePath);
            Assert.Equal(expectedPatientStoragePath, instance.PatientStoragePath);
            Assert.Equal(expectedInstanceStoragePath, instance.InstanceStorageFullPath);

            Assert.True(_fileSystem.Directory.Exists(expectedSeriesStoragePath));
        }
Пример #7
0
        private async Task SaveFiles(IAsyncEnumerable <DicomFile> files, string storagePath, Dictionary <string, InstanceStorageInfo> retrievedInstance)
        {
            Guard.Against.Null(files, nameof(files));
            Guard.Against.Null(storagePath, nameof(storagePath));
            Guard.Against.Null(retrievedInstance, nameof(retrievedInstance));

            var total = 0;
            var saved = 0;

            await foreach (var file in files)
            {
                total++;
                var instance = InstanceStorageInfo.CreateInstanceStorageInfo(file, storagePath, _fileSystem);
                if (retrievedInstance.ContainsKey(instance.SopInstanceUid))
                {
                    _logger.Log(LogLevel.Warning, $"Instance '{instance.SopInstanceUid}' already retrieved/stored.");
                    continue;
                }

                SaveFile(file, instance);
                retrievedInstance.Add(instance.SopInstanceUid, instance);
                saved++;
            }

            _logger.Log(LogLevel.Information, $"Saved {saved} out of {total} instances retrieved");
        }
        public void CreateWithValidData()
        {
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(
                _request,
                _storageRoot,
                "MyAeTitle",
                _fileSystem);

            var expectedAaeStoragePath      = Path.Combine(_storageRoot, "MyAeTitle");
            var expectedPatientStoragePath  = Path.Combine(expectedAaeStoragePath, "PID");
            var expectedSeriesStoragePath   = Path.Combine(expectedPatientStoragePath, Path.Combine(_studyInstanceUid, _seriesInstanceUid));
            var expectedInstanceStoragePath = Path.Combine(expectedSeriesStoragePath, $"{_sopInstanceUid}.dcm");

            Assert.Equal("1.2.3", instance.SopClassUid);
            Assert.Equal("PID", instance.PatientId);
            Assert.Equal(_studyInstanceUid, instance.StudyInstanceUid);
            Assert.Equal(_seriesInstanceUid, instance.SeriesInstanceUid);
            Assert.Equal(_sopInstanceUid, instance.SopInstanceUid);
            Assert.Equal("MyAeTitle", instance.CalledAeTitle);
            Assert.Equal(_storageRoot, instance.StorageRootPath);
            Assert.Equal(expectedAaeStoragePath, instance.AeStoragePath);
            Assert.Equal(expectedPatientStoragePath, instance.PatientStoragePath);
            Assert.Equal(expectedInstanceStoragePath, instance.InstanceStorageFullPath);

            Assert.True(_fileSystem.Directory.Exists(expectedSeriesStoragePath));

            var logger = new Mock <ILogger>();

            logger.Setup(p => p.Information("", ""));
        }
Пример #9
0
        private void RestoreExistingInstances(InferenceRequest inferenceRequest, Dictionary <string, InstanceStorageInfo> retrievedInstances)
        {
            Guard.Against.Null(inferenceRequest, nameof(inferenceRequest));
            Guard.Against.Null(retrievedInstances, nameof(retrievedInstances));

            _logger.Log(LogLevel.Debug, $"Restoring previously retrieved DICOM instances from {inferenceRequest.StoragePath}");
            foreach (var file in _fileSystem.Directory.EnumerateFiles(inferenceRequest.StoragePath, "*.dcm", System.IO.SearchOption.AllDirectories))
            {
                if (_dicomToolkit.HasValidHeader(file))
                {
                    var dicomFile = _dicomToolkit.Open(file);
                    var instance  = InstanceStorageInfo.CreateInstanceStorageInfo(dicomFile, inferenceRequest.StoragePath, _fileSystem);
                    if (retrievedInstances.ContainsKey(instance.SopInstanceUid))
                    {
                        continue;
                    }
                    retrievedInstances.Add(instance.SopInstanceUid, instance);
                    _logger.Log(LogLevel.Debug, $"Restored previously retrieved instance {instance.SopInstanceUid}");
                }
                else
                {
                    _logger.Log(LogLevel.Warning, $"Unable to restore previously retrieved instance from {file}; file does not contain valid DICOM header.");
                }
            }
        }
Пример #10
0
        private async Task RetrieveInstances(IDicomWebClient dicomWebClient, string studyInstanceUid, RequestedSeries series, string storagePath, Dictionary <string, InstanceStorageInfo> retrievedInstance)
        {
            Guard.Against.NullOrWhiteSpace(studyInstanceUid, nameof(studyInstanceUid));
            Guard.Against.Null(series, nameof(series));
            Guard.Against.Null(storagePath, nameof(storagePath));
            Guard.Against.Null(retrievedInstance, nameof(retrievedInstance));

            foreach (var instance in series.Instances)
            {
                if (instance.IsRetrieved)
                {
                    continue;
                }
                foreach (var sopInstanceUid in instance.SopInstanceUid)
                {
                    _logger.Log(LogLevel.Information, $"Retrieving instance {sopInstanceUid}");
                    var file = await dicomWebClient.Wado.Retrieve(studyInstanceUid, series.SeriesInstanceUid, sopInstanceUid);

                    var instanceStorageInfo = InstanceStorageInfo.CreateInstanceStorageInfo(file, storagePath, _fileSystem);
                    if (retrievedInstance.ContainsKey(instanceStorageInfo.SopInstanceUid))
                    {
                        _logger.Log(LogLevel.Warning, $"Instance '{instanceStorageInfo.SopInstanceUid}' already retrieved/stored.");
                        continue;
                    }

                    SaveFile(file, instanceStorageInfo);
                    retrievedInstance.Add(instanceStorageInfo.SopInstanceUid, instanceStorageInfo);
                }
                instance.IsRetrieved = true;
            }
        }
        /// <summary>
        /// Saves specified <code>InstanceStorage</code> to disk.
        /// </summary>
        /// <param name="request">Instance of <code>DicomCStoreRequest</code> to be stored to disk.</param>
        /// <param name="instanceStorage">Instance of <code>InstanceStorage</code></param>
        public void Save(DicomCStoreRequest request, InstanceStorageInfo instanceStorage)
        {
            Guard.Against.Null(instanceStorage, nameof(instanceStorage));

            if (ShouldBeIgnored(instanceStorage.SopClassUid))
            {
                _logger.Log(LogLevel.Warning, "Instance with SOP Class {0} ignored based on configured AET {1}", instanceStorage.SopClassUid, Configuration.AeTitle);
                return;
            }

            Policy.Handle <Exception>()
            .WaitAndRetry(3,
                          (retryAttempt) =>
            {
                return(retryAttempt == 1 ? TimeSpan.FromMilliseconds(250) : TimeSpan.FromMilliseconds(500));
            },
                          (exception, retryCount, context) =>
            {
                _logger.Log(LogLevel.Error, "Failed to save instance, retry count={retryCount}: {exception}", retryCount, exception);
            })
            .Execute(() =>
            {
                if (ShouldSaveInstance(instanceStorage))
                {
                    _logger.Log(LogLevel.Information, "Saving {path}.", instanceStorage.InstanceStorageFullPath);
                    _dicomToolkit.Save(request.File, instanceStorage.InstanceStorageFullPath);
                    _logger.Log(LogLevel.Debug, "Instance saved successfully.");
                    _instanceStoredNotificationService.NewInstanceStored(instanceStorage);
                    _logger.Log(LogLevel.Information, "Instance stored and notified successfully.");
                }
            });
        }
 public void CreateWithoutStorageRootFullPathShallThrow()
 {
     Assert.Throws <ArgumentException>(() =>
     {
         InstanceStorageInfo.CreateInstanceStorageInfo(
             _request,
             string.Empty,
             "AETITLE");
     });
 }
 public void CreateWithNullDicomCStoreRequestShallThrow()
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         InstanceStorageInfo.CreateInstanceStorageInfo(
             null,
             _storageRoot,
             "AETITLE");
     });
 }
 public void CreateWithoutSourceAeTitleShallThrow()
 {
     Assert.Throws <ArgumentException>(() =>
     {
         InstanceStorageInfo.CreateInstanceStorageInfo(
             _request,
             _storageRoot,
             " ");
     });
 }
Пример #15
0
        public void QueueInstance(InstanceStorageInfo workItem)
        {
            if (workItem is null)
            {
                throw new ArgumentNullException(nameof(workItem));
            }

            _workItems.Add(workItem);
            _logger.Log(LogLevel.Debug, "Instance added to cleanup queue {0}. Queue size: {1}", workItem.SopInstanceUid, _workItems.Count);
        }
        public static InstanceStorageInfo GenerateInstance(
            string storageRootFullPath,
            string calledAeTitle,
            uint associationId     = 1,
            IFileSystem fileSystem = null)
        {
            fileSystem = fileSystem ?? new MockFileSystem();
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(
                GenerateDicomCStoreRequest(),
                storageRootFullPath,
                calledAeTitle,
                associationId,
                fileSystem ?? new MockFileSystem());

            fileSystem.File.Create(instance.InstanceStorageFullPath).Close();
            return(instance);
        }
Пример #17
0
        public async Task ShallDeleteFiles()
        {
            var files = new List <InstanceStorageInfo>()
            {
                InstanceStorageInfo.CreateInstanceStorageInfo(GenerateRequest(), "/test", "AET", _fileSystem),
                InstanceStorageInfo.CreateInstanceStorageInfo(GenerateRequest(), "/test", "AET", _fileSystem),
                InstanceStorageInfo.CreateInstanceStorageInfo(GenerateRequest(), "/test", "AET", _fileSystem)
            };

            foreach (var file in files)
            {
                _fileSystem.File.Create(file.InstanceStorageFullPath);
            }

            var cancellationTokenSource = new CancellationTokenSource();
            var stack = new Stack <InstanceStorageInfo>(files);

            _queue.Setup(p => p.Dequeue(It.IsAny <CancellationToken>()))
            .Returns(() =>
            {
                if (stack.TryPop(out InstanceStorageInfo result))
                {
                    return(result);
                }

                cancellationTokenSource.Cancel();
                return(null);
            });

            await _service.StartAsync(cancellationTokenSource.Token);

            while (!cancellationTokenSource.IsCancellationRequested)
            {
                Thread.Sleep(100);
            }

            _queue.Verify(p => p.Dequeue(It.IsAny <CancellationToken>()), Times.AtLeast(3));

            foreach (var file in files)
            {
                Assert.False(_fileSystem.File.Exists(file.InstanceStorageFullPath));
            }
            _logger.VerifyLogging("Cancellation requested.", LogLevel.Information, Times.Once());
        }
        /// <summary>
        /// Determines if the instance exists and if shall be overwritten.
        /// </summary>
        /// <returns>true if instance should be saved; false otherwise.</returns>
        private bool ShouldSaveInstance(InstanceStorageInfo instanceStorage)
        {
            var shouldSaveInstance = false;

            if (!_fileSystem.File.Exists(instanceStorage.InstanceStorageFullPath))
            {
                shouldSaveInstance = true;
            }
            else if ((_fileSystem.File.Exists(instanceStorage.InstanceStorageFullPath) && Configuration.OverwriteSameInstance))
            {
                _logger.Log(LogLevel.Information, "Overwriting existing instance.");
                shouldSaveInstance = true;
            }
            else
            {
                _logger.Log(LogLevel.Information, "Instance already exists, skipping.");
            }
            return(shouldSaveInstance);
        }
        public void ShallRespectRetryPolicyOnFailures()
        {
            _dicomToolkit.Setup(p => p.Save(It.IsAny <DicomFile>(), It.IsAny <string>())).Throws <Exception>();

            var config = new ClaraApplicationEntity();

            config.AeTitle   = "my-aet";
            config.Processor = "Nvidia.Clara.DicomAdapter.Test.Unit.MockJobProcessor, Nvidia.Clara.Dicom.Test.Unit";
            var handler = new ApplicationEntityHandler(_serviceProvider, config, _rootStoragePath, _cancellationTokenSource.Token, _fileSystem);

            var request  = GenerateRequest();
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _rootStoragePath, config.AeTitle, _fileSystem);

            var exception = Assert.Throws <Exception>(() =>
            {
                handler.Save(request, instance);
            });

            _logger.VerifyLogging(LogLevel.Error, Times.Exactly(3));
            _dicomToolkit.Verify(p => p.Save(It.IsAny <DicomFile>(), It.IsAny <string>()), Times.Exactly(4));
        }
Пример #20
0
        public void WorkflowTest()
        {
            var service  = new InstanceStoredNotificationService(_logger.Object, _cleanupQueue.Object);
            var observer = new Mock <IObserver <InstanceStorageInfo> >();

            observer.Setup(p => p.OnNext(It.IsAny <InstanceStorageInfo>()));

            var cancel   = service.Subscribe(observer.Object);
            var request  = GenerateRequest();
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, "/storage", "AET", new MockFileSystem());

            service.NewInstanceStored(instance);
            service.NewInstanceStored(instance);
            service.NewInstanceStored(instance);

            observer.Verify(p => p.OnNext(It.IsAny <InstanceStorageInfo>()), Times.Exactly(3));

            cancel.Dispose();
            observer.Reset();
            service.NewInstanceStored(instance);
            observer.Verify(p => p.OnNext(It.IsAny <InstanceStorageInfo>()), Times.Never());
        }
Пример #21
0
        public override void HandleInstance(InstanceStorageInfo value)
        {
            if (value is null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            ;
            if (!value.CalledAeTitle.Equals(_configuration.AeTitle))
            {
                throw new InstanceNotSupportedException(value);
            }
            ;


            if (!_dicomToolkit.TryGetString(value.InstanceStorageFullPath, _grouping, out string key) ||
                string.IsNullOrWhiteSpace(key))
            {
                _logger.Log(LogLevel.Error, "Instance missing required DICOM key for grouping by {0}, ignoring", _grouping.ToString());
                return;
            }

            InstanceCollection collection = null;

            lock (SyncRoot)
            {
                if (_instances.TryGetValue(key, out InstanceCollection val))
                {
                    collection = val;
                }
                else
                {
                    collection = new InstanceCollection(key);
                    _instances.Add(key, collection);
                    _logger.Log(LogLevel.Debug, "New collection created for {0}", key);
                }
                collection.AddInstance(value);
            }
            _logger.Log(LogLevel.Debug, "Instance received and added with key {0}", key);
        }
Пример #22
0
        private void SaveFile(DicomFile file, InstanceStorageInfo instanceStorageInfo)
        {
            Guard.Against.Null(file, nameof(file));
            Guard.Against.Null(instanceStorageInfo, nameof(instanceStorageInfo));

            Policy.Handle <Exception>()
            .WaitAndRetry(3,
                          (retryAttempt) =>
            {
                return(retryAttempt == 1 ? TimeSpan.FromMilliseconds(250) : TimeSpan.FromMilliseconds(500));
            },
                          (exception, retryCount, context) =>
            {
                _logger.Log(LogLevel.Error, "Failed to save instance, retry count={retryCount}: {exception}", retryCount, exception);
            })
            .Execute(() =>
            {
                _logger.Log(LogLevel.Information, "Saving DICOM instance {path}.", instanceStorageInfo.InstanceStorageFullPath);
                _dicomToolkit.Save(file, instanceStorageInfo.InstanceStorageFullPath);
                _logger.Log(LogLevel.Debug, "Instance saved successfully.");
            });
        }
        public void ShallIngoreInstancesWithConfiguredSopClassUids()
        {
            _dicomToolkit.Setup(p => p.Save(It.IsAny <DicomFile>(), It.IsAny <string>()));

            var config = new ClaraApplicationEntity();

            config.AeTitle           = "my-aet";
            config.IgnoredSopClasses = new List <string>()
            {
                DicomUID.SecondaryCaptureImageStorage.UID
            };
            config.Processor = "Nvidia.Clara.DicomAdapter.Test.Unit.MockJobProcessor, Nvidia.Clara.Dicom.Test.Unit";
            var handler = new ApplicationEntityHandler(_serviceProvider, config, _rootStoragePath, _cancellationTokenSource.Token, _fileSystem);

            var request  = GenerateRequest();
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _rootStoragePath, config.AeTitle, _fileSystem);

            handler.Save(request, instance);

            _logger.VerifyLogging($"Instance with SOP Class {DicomUID.SecondaryCaptureImageStorage.UID} ignored based on configured AET {config.AeTitle}", LogLevel.Warning, Times.Once());
            _dicomToolkit.Verify(p => p.Save(It.IsAny <DicomFile>(), It.IsAny <string>()), Times.Never());
        }
        public void ShallQueueAndDequeueItems()
        {
            for (var i = 0; i < 10; i++)
            {
                _queue.QueueInstance(InstanceStorageInfo.CreateInstanceStorageInfo(
                                         GenerateRequest(),
                                         "/test",
                                         "AET",
                                         new MockFileSystem()
                                         ));
            }

            _cancellationTokenSource.CancelAfter(500);
            var items = new List <InstanceStorageInfo>();

            for (var i = 0; i < 10; i++)
            {
                items.Add(_queue.Dequeue(_cancellationTokenSource.Token));
            }

            Assert.Equal(10, items.Count);
        }
Пример #25
0
        private void GenerateInstances()
        {
            var request  = GenerateRequest(_patient1, _study1, _series1);
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _fileSystem.Path.DirectorySeparatorChar.ToString(), _aeTitle, 1, _fileSystem);

            _instances.Add(instance);
            _fileSystem.File.CreateText(instance.InstanceStorageFullPath);

            request  = GenerateRequest(_patient1, _study1, _series2);
            instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _fileSystem.Path.DirectorySeparatorChar.ToString(), _aeTitle, 1, _fileSystem);
            _instances.Add(instance);
            _fileSystem.File.CreateText(instance.InstanceStorageFullPath);

            request  = GenerateRequest(_patient1, _study2, _series3);
            instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _fileSystem.Path.DirectorySeparatorChar.ToString(), _aeTitle, 1, _fileSystem);
            _instances.Add(instance);
            _fileSystem.File.CreateText(instance.InstanceStorageFullPath);

            request  = GenerateRequest(_patient2, _study3, _series4);
            instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, _fileSystem.Path.DirectorySeparatorChar.ToString(), _aeTitle, 1, _fileSystem);
            _instances.Add(instance);
            _fileSystem.File.CreateText(instance.InstanceStorageFullPath);
        }
        public void HandleCStoreRequest(DicomCStoreRequest request, string calledAeTitle, uint associationId)
        {
            Guard.Against.Null(request, nameof(request));

            if (!_aeTitleManagers.ContainsKey(calledAeTitle))
            {
                throw new ArgumentException($"Called AE Title '{calledAeTitle}' is not configured");
            }

            _logger.Log(LogLevel.Information, "Preparing to save instance from {callingAeTitle}.", calledAeTitle);

            var instanceStorage = InstanceStorageInfo.CreateInstanceStorageInfo(request, Configuration.Value.Storage.Temporary, calledAeTitle, associationId);

            using (_logger.BeginScope("SOPInstanceUID={0}", instanceStorage.SopInstanceUid))
            {
                _logger.Log(LogLevel.Information, "Patient ID: {PatientId}", instanceStorage.PatientId);
                _logger.Log(LogLevel.Information, "Study Instance UID: {StudyInstanceUid}", instanceStorage.StudyInstanceUid);
                _logger.Log(LogLevel.Information, "Series Instance UID: {SeriesInstanceUid}", instanceStorage.SeriesInstanceUid);
                _logger.Log(LogLevel.Information, "Storage File Path: {InstanceStorageFullPath}", instanceStorage.InstanceStorageFullPath);

                _aeTitleManagers[calledAeTitle].Value.Save(request, instanceStorage);
                _logger.Log(LogLevel.Debug, "Instance saved with handler", instanceStorage.InstanceStorageFullPath);
            }
        }
Пример #27
0
        public void NewInstanceStored_NoSupportedObservers()
        {
            var request  = GenerateRequest();
            var instance = InstanceStorageInfo.CreateInstanceStorageInfo(request, "/storage", "AET", new MockFileSystem());

            _cleanupQueue.Setup(p => p.QueueInstance(It.IsAny <InstanceStorageInfo>()));

            var service  = new InstanceStoredNotificationService(_logger.Object, _cleanupQueue.Object);
            var observer = new Mock <IObserver <InstanceStorageInfo> >();

            observer.Setup(p => p.OnNext(It.IsAny <InstanceStorageInfo>())).Throws(new InstanceNotSupportedException(instance));

            var cancel = service.Subscribe(observer.Object);

            service.NewInstanceStored(instance);

            observer.Verify(p => p.OnNext(It.IsAny <InstanceStorageInfo>()), Times.Once());
            _cleanupQueue.Verify(p => p.QueueInstance(instance), Times.Once());

            cancel.Dispose();
            observer.Reset();
            service.NewInstanceStored(instance);
            observer.Verify(p => p.OnNext(It.IsAny <InstanceStorageInfo>()), Times.Never());
        }
 public override void HandleInstance(InstanceStorageInfo value)
 {
     //noop
 }
 public InstanceNotSupportedException(InstanceStorageInfo instance)
 {
     Instance = instance ?? throw new System.ArgumentNullException(nameof(instance));
 }