Пример #1
0
        private void ValidateProcessor(ClaraApplicationEntity claraAe)
        {
            Guard.Against.Null(claraAe, nameof(claraAe));

            if (!claraAe.IsValid(_dicomAdapterRepository.AsQueryable().Select(p => p.AeTitle), out IList <string> validationErrors))
            {
                throw new ConfigurationException(string.Join(Environment.NewLine, validationErrors));
            }

            ProcessorValidationAttribute attribute;

            try
            {
                var type = typeof(JobProcessorBase).GetType <JobProcessorBase>(claraAe.Processor);
                attribute = (ProcessorValidationAttribute)Attribute.GetCustomAttributes(type, typeof(ProcessorValidationAttribute)).FirstOrDefault();
            }
            catch (ConfigurationException ex)
            {
                throw new ConfigurationException($"Invalid job processor: {ex.Message}.", ex);
            }

            if (attribute is null)
            {
                throw new ConfigurationException($"Processor type {claraAe.Processor} does not have a `ProcessorValidationAttribute` defined.");
            }

            var validator = attribute.ValidatorType.CreateInstance <IJobProcessorValidator>(_serviceProvider);

            validator.Validate(claraAe.AeTitle, claraAe.ProcessorSettings);
        }
Пример #2
0
        public async void Create_ShallReturnBadRequestOnAddFailure()
        {
            var aeTitle      = "AET";
            var claraAeTitle = new ClaraApplicationEntity
            {
                Name      = aeTitle,
                Processor = typeof(MockJobProcessor).AssemblyQualifiedName,
                AeTitle   = aeTitle,
            };

            _repository.Setup(p => p.AddAsync(It.IsAny <ClaraApplicationEntity>(), It.IsAny <CancellationToken>())).Throws(new Exception("error"));

            var result = await _controller.Create(claraAeTitle);

            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("Error adding new Clara Application Entity.", problem.Title);
            Assert.Equal($"error", problem.Detail);
            Assert.Equal((int)HttpStatusCode.InternalServerError, problem.Status);

            _repository.Verify(p => p.AddAsync(It.IsAny <ClaraApplicationEntity>(), It.IsAny <CancellationToken>()), Times.Once());
        }
Пример #3
0
        public void ClaraApplicationEntity_Valid()
        {
            var claraApplicationEntity = new ClaraApplicationEntity();

            claraApplicationEntity.AeTitle = "AET";
            Assert.True(claraApplicationEntity.IsValid(new List <string>(), out _));
        }
        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());
        }
Пример #5
0
        public async void Create_ShallReturnCreatedJson()
        {
            var response = new HttpOperationResponse <object>();

            response.Response         = new HttpResponseMessage(HttpStatusCode.OK);
            response.Response.Content = new StringContent("Go!Clara");
            _kubernetesClient
            .Setup(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()))
            .Returns(() =>
            {
                return(Task.FromResult(response));
            });

            var claraAeTitle = new ClaraApplicationEntity
            {
                Name = "MySCP"
            };

            var result = await _controller.Create(claraAeTitle);

            _kubernetesClient.Verify(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()), Times.Once());
            Assert.NotNull(result);
            var contentResult = result.Result as ContentResult;

            Assert.NotNull(contentResult);
            Assert.Equal(response.Response.Content.AsString(), contentResult.Content);
        }
Пример #6
0
        public AeTitleJobProcessor(
            ClaraApplicationEntity configuration,
            IInstanceStoredNotificationService instanceStoredNotificationService,
            ILoggerFactory loggerFactory,
            IJobRepository jobStore,
            IInstanceCleanupQueue cleanupQueue,
            IDicomToolkit dicomToolkit,
            CancellationToken cancellationToken) : base(instanceStoredNotificationService, loggerFactory, jobStore, cleanupQueue, cancellationToken)
        {
            if (loggerFactory is null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
            _dicomToolkit  = dicomToolkit ?? throw new ArgumentNullException(nameof(dicomToolkit));
            _collections   = new Dictionary <string, InstanceCollection>();
            _pipelines     = new Dictionary <string, string>();

            _logger = loggerFactory.CreateLogger <AeTitleJobProcessor>();

            _timer           = new System.Timers.Timer(1000);
            _timer.AutoReset = false;
            _timer.Elapsed  += OnTimedEvent;
            _timer.Enabled   = true;

            _jobs = new BlockingCollection <InstanceCollection>();

            InitializeSettings();
            _jobProcessingTask = ProcessJobs();
        }
Пример #7
0
        public async void Create_ShallPropagateErrorBackToCaller()
        {
            var response = new HttpOperationResponse <object>();

            response.Response         = new HttpResponseMessage(HttpStatusCode.OK);
            response.Response.Content = new StringContent("Go!Clara!");
            _kubernetesClient
            .Setup(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()))
            .Throws(new HttpOperationException("error message")
            {
                Response = new HttpResponseMessageWrapper(new HttpResponseMessage(HttpStatusCode.Conflict), "error content")
            });

            var claraAeTitle = new ClaraApplicationEntity
            {
                Name = "MySCP"
            };

            var result = await _controller.Create(claraAeTitle);

            _kubernetesClient.Verify(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()), Times.Once());

            Assert.NotNull(result);
            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("error message", problem.Detail);
            Assert.Equal("error content", problem.Title);
            Assert.Equal((int)HttpStatusCode.Conflict, problem.Status.Value);
        }
Пример #8
0
        public async void Delete_ShallReturnProblemOnFailure()
        {
            var value  = "AET";
            var entity = new ClaraApplicationEntity
            {
                AeTitle = value,
                Name    = value
            };

            _repository.Setup(p => p.FindAsync(It.IsAny <string>())).Returns(Task.FromResult(entity));
            _repository.Setup(p => p.Remove(It.IsAny <ClaraApplicationEntity>())).Throws(new Exception("error"));

            var result = await _controller.Delete(value);

            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("Error deleting Clara Application Entity.", problem.Title);
            Assert.Equal("error", problem.Detail);
            Assert.Equal((int)HttpStatusCode.InternalServerError, problem.Status);
            _repository.Verify(p => p.FindAsync(value), Times.Once());
        }
Пример #9
0
        public async void Create_ShallReturnCreatedJson()
        {
            var mockLogger = new Mock <ILogger <AeTitleJobProcessorValidator> >();

            _serviceProvider.Setup(p => p.GetService(typeof(ILogger <AeTitleJobProcessorValidator>))).Returns(mockLogger.Object);

            var response = new HttpOperationResponse <object>();

            response.Response         = new HttpResponseMessage(HttpStatusCode.OK);
            response.Response.Content = new StringContent("Go!Clara");
            _kubernetesClient
            .Setup(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()))
            .Returns(() =>
            {
                return(Task.FromResult(response));
            });

            var claraAeTitle = new ClaraApplicationEntity
            {
                Name = "MySCP",
                ProcessorSettings = new Dictionary <string, string> {
                    { "pipeline-test", "ABCDEFG" }
                }
            };

            var result = await _controller.Create(claraAeTitle);

            _kubernetesClient.Verify(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()), Times.Once());
            Assert.NotNull(result);
            var contentResult = result.Result as ContentResult;

            Assert.NotNull(contentResult);
            Assert.Equal(response.Response.Content.AsString(), contentResult.Content);
        }
Пример #10
0
        public async Task <ActionResult <ClaraApplicationEntity> > Create(ClaraApplicationEntity item)
        {
            try
            {
                ValidateProcessor(item);
                item.SetDefaultValues();

                await _dicomAdapterRepository.AddAsync(item);

                await _dicomAdapterRepository.SaveChangesAsync();

                _claraAeChangedNotificationService.Notify(new ClaraApplicationChangedEvent(item, ChangedEventType.Added));
                _logger.Log(LogLevel.Information, $"Clara SCP AE Title added AE Title={item.AeTitle}.");
                return(CreatedAtAction(nameof(GetAeTitle), new { aeTitle = item.AeTitle }, item));
            }
            catch (ConfigurationException ex)
            {
                return(Problem(title: "Validation error.", statusCode: (int)System.Net.HttpStatusCode.BadRequest, detail: ex.Message));
            }
            catch (Exception ex)
            {
                _logger.Log(LogLevel.Error, ex, "Error adding new Clara Application Entity.");
                return(Problem(title: "Error adding new Clara Application Entity.", statusCode: (int)System.Net.HttpStatusCode.InternalServerError, detail: ex.Message));
            }
        }
Пример #11
0
        public void ClaraApplicationEntity_ShallThrowOnNull()
        {
            ClaraApplicationEntity claraApplicationEntity = null;

            Assert.Throws <ArgumentNullException>(() => claraApplicationEntity.IsValid(new List <string>(), out _));

            claraApplicationEntity = new ClaraApplicationEntity();
            Assert.Throws <ArgumentNullException>(() => claraApplicationEntity.IsValid(null, out _));
        }
Пример #12
0
 public MockBadJobProcessorValidationFailure(
     ClaraApplicationEntity configuration,
     IInstanceStoredNotificationService instanceStoredNotificationService,
     ILoggerFactory loggerFactory,
     IJobRepository jobStore,
     IInstanceCleanupQueue cleanupQueue,
     CancellationToken cancellationToken) : base(instanceStoredNotificationService, loggerFactory, jobStore, cleanupQueue, cancellationToken)
 {
 }
Пример #13
0
 public MockJobProcessor(
     ClaraApplicationEntity configuration,
     IInstanceStoredNotificationService instanceStoredNotificationService,
     ILoggerFactory loggerFactory,
     IJobRepository jobStore,
     IInstanceCleanupQueue cleanupQueue,
     CancellationToken cancellationToken) : base(instanceStoredNotificationService, loggerFactory, jobStore, cleanupQueue, cancellationToken)
 {
     _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
 }
Пример #14
0
        public void ClaraApplicationEntity_InvalidIfAlreadyExists()
        {
            var claraApplicationEntity = new ClaraApplicationEntity();

            claraApplicationEntity.AeTitle = "AET";
            Assert.False(claraApplicationEntity.IsValid(new List <string>()
            {
                "AET"
            }, out _));
        }
Пример #15
0
        public void ClaraApplicationEntity_InvalidWhenAeTitleIsEmpty()
        {
            var claraApplicationEntity = new ClaraApplicationEntity();

            claraApplicationEntity.AeTitle = "             ";
            Assert.False(claraApplicationEntity.IsValid(new List <string>(), out _));

            claraApplicationEntity.AeTitle = "ABCDEFGHIJKLMNOPQRSTUVW";
            Assert.False(claraApplicationEntity.IsValid(new List <string>(), out _));
        }
 private void AddNewAeTitle(ClaraApplicationEntity entity)
 {
     using (var scope = _serviceScopeFactory.CreateScope())
     {
         if (!_aeTitleManagers.TryAdd(
                 entity.AeTitle,
                 new Lazy <ApplicationEntityHandler>(NewHandler(scope.ServiceProvider, entity))))
         {
             _logger.Log(LogLevel.Error, $"AE Title {0} could not be added to CStore Manager.  Already exits: {1}", entity.AeTitle, _aeTitleManagers.ContainsKey(entity.AeTitle));
         }
         else
         {
             _logger.Log(LogLevel.Information, $"{entity.AeTitle} added to AE Title Manager");
         }
     }
 }
Пример #17
0
        public async void Delete_Returns404IfNotFound()
        {
            var value  = "AET";
            var entity = new ClaraApplicationEntity
            {
                AeTitle = value,
                Name    = value
            };

            _repository.Setup(p => p.FindAsync(It.IsAny <string>())).Returns(Task.FromResult(default(ClaraApplicationEntity)));

            var result = await _controller.Delete(value);

            Assert.IsType <NotFoundResult>(result.Result);
            _repository.Verify(p => p.FindAsync(value), Times.Once());
        }
Пример #18
0
        public AeTitleJobProcessorTest()
        {
            _cancellationTokenSource   = new CancellationTokenSource();
            _configuration             = new ClaraApplicationEntity();
            _loggerNotificationService = new Mock <ILogger <InstanceStoredNotificationService> >();
            _loggerJobProcessorBase    = new Mock <ILogger <JobProcessorBase> >();
            _logger              = new Mock <ILogger <AeTitleJobProcessor> >();
            _cleanupQueue        = new Mock <IInstanceCleanupQueue>();
            _notificationService = new InstanceStoredNotificationService(_loggerNotificationService.Object, _cleanupQueue.Object);
            _loggerFactory       = new Mock <ILoggerFactory>();
            _jobsApi             = new Mock <IJobs>();
            _payloadsApi         = new Mock <IPayloads>();
            _instances           = new List <InstanceStorageInfo>();
            _dicomToolkit        = new Mock <IDicomToolkit>();
            _fileSystem          = new MockFileSystem();

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

            _loggerFactory.Setup(p => p.CreateLogger(It.IsAny <string>())).Returns((string type) =>
            {
                return(_logger.Object);
            });
            string expectedValue = string.Empty;

            _dicomToolkit.Setup(p => p.TryGetString(It.IsAny <string>(), It.IsAny <DicomTag>(), out expectedValue))
            .Callback(new AeTitleJobProcessorTest.OutAction((string path, DicomTag tag, out string value) =>
            {
                var instance = _instances.First(p => p.InstanceStorageFullPath == path);
                value        = tag == DicomTag.PatientID ? instance.PatientId :
                               tag == DicomTag.StudyInstanceUID ? instance.StudyInstanceUid :
                               instance.SeriesInstanceUid;
            })).Returns(true);

            _patient1 = "PATIENT1";
            _patient2 = "PATIENT2";
            _study1   = DicomUIDGenerator.GenerateDerivedFromUUID();
            _study2   = DicomUIDGenerator.GenerateDerivedFromUUID();
            _study3   = DicomUIDGenerator.GenerateDerivedFromUUID();
            _series1  = DicomUIDGenerator.GenerateDerivedFromUUID();
            _series2  = DicomUIDGenerator.GenerateDerivedFromUUID();
            _series3  = DicomUIDGenerator.GenerateDerivedFromUUID();
            _series4  = DicomUIDGenerator.GenerateDerivedFromUUID();
            _aeTitle  = "AET1";

            GenerateInstances();
        }
Пример #19
0
        public async void Create_ShallReturnServiceUnavailableWHenCrdIsDisabled()
        {
            var claraAeTitle = new ClaraApplicationEntity
            {
                Name = "ClaraSCP"
            };

            _configuration.Value.ReadAeTitlesFromCrd = false;
            var result = await _controller.Create(claraAeTitle);

            Assert.NotNull(result);
            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("Reading AE Titles from Kubernetes CRD is not enabled.", problem.Title);
            Assert.Equal(503, problem.Status);
        }
Пример #20
0
        public async void Create_ShallReturnBadRequestOnValidationFailure(string aeTitle, string errorMessage)
        {
            var data = new List <ClaraApplicationEntity>();

            for (int i = 1; i <= 3; i++)
            {
                data.Add(new ClaraApplicationEntity()
                {
                    AeTitle           = $"AET{i}",
                    Name              = $"AET{i}",
                    Processor         = typeof(MockJobProcessor).AssemblyQualifiedName,
                    IgnoredSopClasses = new List <string>()
                    {
                        $"{i}"
                    },
                    ProcessorSettings     = new Dictionary <string, string>(),
                    OverwriteSameInstance = (i % 2 == 0)
                });
            }
            _repository.Setup(p => p.AsQueryable()).Returns(data.AsQueryable());

            var claraAeTitle = new ClaraApplicationEntity
            {
                Name      = aeTitle,
                Processor = typeof(MockJobProcessor).AssemblyQualifiedName,
                AeTitle   = aeTitle,
            };

            var result = await _controller.Create(claraAeTitle);

            Assert.NotNull(result);
            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("Validation error.", problem.Title);
            Assert.Equal(errorMessage, problem.Detail);
            Assert.Equal((int)HttpStatusCode.BadRequest, problem.Status);
        }
        private void ValidateProcessor(ClaraApplicationEntity claraAe)
        {
            Guard.Against.Null(claraAe, nameof(claraAe));

            if (!_configurationValidator.IsClaraAeTitleValid(_dicomAdapterConfiguration.Value.Dicom.Scp.AeTitles, "dicom>scp>ae-title", claraAe, true))
            {
                throw new Exception("Invalid Clara (local) AE Title specs provided or AE Title already exits");
            }

            var type      = typeof(JobProcessorBase).GetType <JobProcessorBase>(claraAe.Processor);
            var attribute = (ProcessorValidationAttribute)Attribute.GetCustomAttributes(type, typeof(ProcessorValidationAttribute)).FirstOrDefault();

            if (attribute == null)
            {
                throw new ConfigurationException($"Processor type {claraAe.Processor} does not have a `ProcessorValidationAttribute` defined.");
            }

            var validator = attribute.ValidatorType.CreateInstance <IJobProcessorValidator>(_serviceProvider);

            validator.Validate(claraAe.AeTitle, claraAe.ProcessorSettings);
        }
        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));
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="serviceProvider">Instance of IServiceProvide for dependency injection.</param>
        /// <param name="applicationEntity">ClaraApplicationEntity configuration to be used.</param>
        /// <param name="storageRootFullPath">Temporary storage path location</param>
        /// <param name="iFileSystem">instance of IFileSystem</param>
        public ApplicationEntityHandler(IServiceProvider serviceProvider, ClaraApplicationEntity applicationEntity, string storageRootFullPath, CancellationToken cancellationToken, IFileSystem iFileSystem)
        {
            Guard.Against.NullOrWhiteSpace(storageRootFullPath, nameof(storageRootFullPath));

            _serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
            Configuration    = applicationEntity ?? throw new ArgumentNullException(nameof(applicationEntity));
            _loggerFactory   = _serviceProvider.GetService <ILoggerFactory>();

            _logger               = _loggerFactory.CreateLogger <ApplicationEntityHandler>();
            _dicomToolkit         = _serviceProvider.GetService <IDicomToolkit>();
            _cancellationToken    = cancellationToken;
            _fileSystem           = iFileSystem ?? throw new ArgumentNullException(nameof(iFileSystem));
            AeStorageRootFullPath = _fileSystem.Path.Combine(storageRootFullPath, applicationEntity.AeTitle.RemoveInvalidPathChars());

            _instanceStoredNotificationService = (IInstanceStoredNotificationService)serviceProvider.GetService(typeof(IInstanceStoredNotificationService)) ?? throw new ArgumentNullException("IInstanceStoredNotificationService service not configured");

            _jobProcessor = typeof(JobProcessorBase).CreateInstance <JobProcessorBase>(serviceProvider, Configuration.Processor, Configuration, _cancellationToken);
            _logger.Log(LogLevel.Information, "Clara AE Title {0} configured with temporary storage location {1}", applicationEntity.AeTitle, AeStorageRootFullPath);

            CleanRootPath();
        }
Пример #24
0
        public async void Create_ShallPropagateErrorBackToCaller()
        {
            var mockLogger = new Mock <ILogger <AeTitleJobProcessorValidator> >();

            _serviceProvider.Setup(p => p.GetService(typeof(ILogger <AeTitleJobProcessorValidator>))).Returns(mockLogger.Object);

            var response = new HttpOperationResponse <object>();

            response.Response         = new HttpResponseMessage(HttpStatusCode.OK);
            response.Response.Content = new StringContent("Go!Clara!");
            _kubernetesClient
            .Setup(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()))
            .Throws(new HttpOperationException("error message")
            {
                Response = new HttpResponseMessageWrapper(new HttpResponseMessage(HttpStatusCode.Conflict), "error content")
            });

            var claraAeTitle = new ClaraApplicationEntity
            {
                Name = "MySCP",
                ProcessorSettings = new Dictionary <string, string> {
                    { "pipeline-test", "ABCDEFG" }
                }
            };

            var result = await _controller.Create(claraAeTitle);

            _kubernetesClient.Verify(p => p.CreateNamespacedCustomObjectWithHttpMessagesAsync(It.IsAny <CustomResourceDefinition>(), It.IsAny <object>()), Times.Once());

            Assert.NotNull(result);
            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("error message", problem.Detail);
            Assert.Equal("error content", problem.Title);
            Assert.Equal((int)HttpStatusCode.Conflict, problem.Status.Value);
        }
Пример #25
0
        public async void Delete_ReturnsDeleted()
        {
            var value  = "AET";
            var entity = new ClaraApplicationEntity
            {
                AeTitle = value,
                Name    = value
            };

            _repository.Setup(p => p.FindAsync(It.IsAny <string>())).Returns(Task.FromResult(entity));

            _repository.Setup(p => p.Remove(It.IsAny <ClaraApplicationEntity>()));
            _repository.Setup(p => p.SaveChangesAsync(It.IsAny <CancellationToken>()));

            var result = await _controller.Delete(value);

            Assert.NotNull(result.Value);
            Assert.Equal(value, result.Value.AeTitle);
            _repository.Verify(p => p.FindAsync(value), Times.Once());
            _repository.Verify(p => p.Remove(entity), Times.Once());
            _repository.Verify(p => p.SaveChangesAsync(It.IsAny <CancellationToken>()), Times.Once());
        }
Пример #26
0
        public async void Create_ShallReturnCreatedAtAction()
        {
            var aeTitle      = "AET";
            var claraAeTitle = new ClaraApplicationEntity
            {
                Name      = aeTitle,
                Processor = typeof(MockJobProcessor).AssemblyQualifiedName,
                AeTitle   = aeTitle,
            };

            _aeChangedNotificationService.Setup(p => p.Notify(It.IsAny <ClaraApplicationChangedEvent>()));
            _repository.Setup(p => p.AddAsync(It.IsAny <ClaraApplicationEntity>(), It.IsAny <CancellationToken>()));
            _repository.Setup(p => p.SaveChangesAsync(It.IsAny <CancellationToken>()));

            var result = await _controller.Create(claraAeTitle);

            Assert.IsType <CreatedAtActionResult>(result.Result);

            _aeChangedNotificationService.Verify(p => p.Notify(It.Is <ClaraApplicationChangedEvent>(x => x.ApplicationEntity == claraAeTitle)), Times.Once());
            _repository.Verify(p => p.AddAsync(It.IsAny <ClaraApplicationEntity>(), It.IsAny <CancellationToken>()), Times.Once());
            _repository.Verify(p => p.SaveChangesAsync(It.IsAny <CancellationToken>()), Times.Once());
        }
Пример #27
0
        public async void Create_ShallReturnBadRequestWithJobProcesssorValidationFailure()
        {
            var aeTitle      = "AET";
            var claraAeTitle = new ClaraApplicationEntity
            {
                Name      = aeTitle,
                Processor = typeof(MockBadJobProcessorValidationFailure).AssemblyQualifiedName,
                AeTitle   = aeTitle,
            };

            var result = await _controller.Create(claraAeTitle);

            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("Validation error.", problem.Title);
            Assert.Equal($"validation failed", problem.Detail);
            Assert.Equal((int)HttpStatusCode.BadRequest, problem.Status);
        }
        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());
        }
Пример #29
0
        public async void Create_ShallReturnBadRequestWHenCrdIsDisabled(string aeTitle)
        {
            var claraAeTitle = new ClaraApplicationEntity
            {
                Name = aeTitle
            };

            _configuration.Value.Dicom.Scp.AeTitles.Add(new ClaraApplicationEntity()
            {
                Name = "ExistingScp"
            });
            var result = await _controller.Create(claraAeTitle);

            Assert.NotNull(result);
            var objectResult = result.Result as ObjectResult;

            Assert.NotNull(objectResult);
            var problem = objectResult.Value as ProblemDetails;

            Assert.NotNull(problem);
            Assert.Equal("Invalid Clara (local) AE Title specs provided or AE Title already exits", problem.Title);
            Assert.Equal((int)HttpStatusCode.BadRequest, problem.Status);
        }
        public void ShallRemoveExistingDataAtStartup()
        {
            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 rootPath = _fileSystem.Path.Combine(_rootStoragePath, config.AeTitle.RemoveInvalidPathChars());

            _fileSystem.Directory.CreateDirectory(rootPath);
            _fileSystem.File.Create(_fileSystem.Path.Combine(rootPath, "test.txt"));
            #pragma warning disable xUnit2013
            Assert.Equal(1, _fileSystem.Directory.GetFiles(rootPath).Count());

            var handler = new ApplicationEntityHandler(_serviceProvider, config, _rootStoragePath, _cancellationTokenSource.Token, _fileSystem);

            _logger.VerifyLogging($"Existing AE Title storage directory {rootPath} found, deleting...", LogLevel.Information, Times.Once());
            _logger.VerifyLogging($"Existing AE Title storage directory {rootPath} deleted.", LogLevel.Information, Times.Once());
            Assert.Equal(0, _fileSystem.Directory.GetFiles(rootPath).Count());
            #pragma warning restore  xUnit2013
        }