public void SetUpSuite() { SetUpDefaults(); // Create the test Series/Image exchanges Options.RabbitOptions.RabbitMqControlExchangeName = "TEST.ControlExchange"; var tester = new MicroserviceTester(Options.RabbitOptions); tester.CreateExchange(Options.DicomTagReaderOptions.ImageProducerOptions.ExchangeName, TestImageQueueName); tester.CreateExchange(Options.DicomTagReaderOptions.SeriesProducerOptions.ExchangeName, TestSeriesQueueName); tester.CreateExchange(Options.RabbitOptions.FatalLoggingExchange, null); tester.CreateExchange(Options.RabbitOptions.RabbitMqControlExchangeName, null); tester.Shutdown(); _testConnection = new ConnectionFactory { HostName = Options.RabbitOptions.RabbitMqHostName, Port = Options.RabbitOptions.RabbitMqHostPort, VirtualHost = Options.RabbitOptions.RabbitMqVirtualHost, UserName = Options.RabbitOptions.RabbitMqUserName, Password = Options.RabbitOptions.RabbitMqPassword }.CreateConnection("TestConnection"); _testModel = _testConnection.CreateModel(); MockHost = Mock.Of <IMicroserviceHost>(); }
public void Test_DodgyTagNames() { _helper.TruncateTablesIfExists(); DirectoryInfo d = new DirectoryInfo(Path.Combine(TestContext.CurrentContext.TestDirectory, nameof(Test_DodgyTagNames))); d.Create(); var fi = TestData.Create(new FileInfo(Path.Combine(d.FullName, "MyTestFile.dcm"))); var fi2 = TestData.Create(new FileInfo(Path.Combine(d.FullName, "MyTestFile2.dcm"))); DicomFile dcm; using (var stream = File.OpenRead(fi.FullName)) { dcm = DicomFile.Open(stream); dcm.Dataset.AddOrUpdate(DicomTag.PrintRETIRED, "FISH"); dcm.Dataset.AddOrUpdate(DicomTag.Date, new DateTime(2001, 01, 01)); dcm.Save(fi2.FullName); } var adder = new TagColumnAdder(DicomTypeTranslaterReader.GetColumnNameForTag(DicomTag.Date, false), "datetime2", _helper.ImageTableInfo, new AcceptAllCheckNotifier()); adder.Execute(); adder = new TagColumnAdder(DicomTypeTranslaterReader.GetColumnNameForTag(DicomTag.PrintRETIRED, false), "datetime2", _helper.ImageTableInfo, new AcceptAllCheckNotifier()); adder.Execute(); fi.Delete(); File.Move(fi2.FullName, fi.FullName); //creates the queues, exchanges and bindings var tester = new MicroserviceTester(_globals.RabbitOptions, _globals.DicomRelationalMapperOptions); tester.CreateExchange(_globals.RabbitOptions.FatalLoggingExchange, null); using (var host = new DicomRelationalMapperHost(_globals)) { host.Start(); using (var timeline = new TestTimeline(tester)) { timeline.SendMessage(_globals.DicomRelationalMapperOptions, _helper.GetDicomFileMessage(_globals.FileSystemOptions.FileSystemRoot, fi)); //start the timeline timeline.StartTimeline(); Thread.Sleep(TimeSpan.FromSeconds(10)); new TestTimelineAwaiter().Await(() => host.Consumer.AckCount >= 1, null, 30000, () => host.Consumer.DleErrors); Assert.AreEqual(1, _helper.SeriesTable.GetRowCount(), "SeriesTable did not have the expected number of rows in LIVE"); Assert.AreEqual(1, _helper.StudyTable.GetRowCount(), "StudyTable did not have the expected number of rows in LIVE"); Assert.AreEqual(1, _helper.ImageTable.GetRowCount(), "ImageTable did not have the expected number of rows in LIVE"); host.Stop("Test end"); } } tester.Shutdown(); }
public void TestClassifierName_ValidClassifier() { var options = new GlobalOptionsFactory().Load(); var testDcm = new FileInfo(Path.Combine(TestContext.CurrentContext.TestDirectory, nameof(TestClassifierName_ValidClassifier), "f1.dcm")); Path.Combine(TestContext.CurrentContext.TestDirectory, nameof(TestClassifierName_ValidClassifier), "f1.dcm"); TestData.Create(testDcm); using (var tester = new MicroserviceTester(options.RabbitOptions, options.IsIdentifiableOptions)) { tester.CreateExchange(options.IsIdentifiableOptions.IsIdentifiableProducerOptions.ExchangeName, null); options.IsIdentifiableOptions.ClassifierType = typeof(RejectAllClassifier).FullName; options.IsIdentifiableOptions.DataDirectory = TestContext.CurrentContext.TestDirectory; var host = new IsIdentifiableHost(options, new IsIdentifiableServiceOptions()); Assert.IsNotNull(host); host.Start(); tester.SendMessage(options.IsIdentifiableOptions, new ExtractedFileStatusMessage() { DicomFilePath = "yay.dcm", OutputFilePath = testDcm.FullName, ProjectNumber = "100", ExtractionDirectory = "./fish", StatusMessage = "yay!", Status = ExtractedFileStatus.Anonymised }); var awaiter = new TestTimelineAwaiter(); awaiter.Await(() => host.Consumer.AckCount == 1); } }
public void Test_FileCopierHost_HappyPath() { GlobalOptions globals = new GlobalOptionsFactory().Load(); globals.FileSystemOptions.FileSystemRoot = "root"; globals.FileSystemOptions.ExtractRoot = "exroot"; using var tester = new MicroserviceTester(globals.RabbitOptions, globals.FileCopierOptions); string outputQueueName = globals.FileCopierOptions.CopyStatusProducerOptions.ExchangeName.Replace("Exchange", "Queue"); tester.CreateExchange( globals.FileCopierOptions.CopyStatusProducerOptions.ExchangeName, outputQueueName, false, globals.FileCopierOptions.NoVerifyRoutingKey); var mockFileSystem = new MockFileSystem(); mockFileSystem.AddDirectory(globals.FileSystemOptions.FileSystemRoot); mockFileSystem.AddDirectory(globals.FileSystemOptions.ExtractRoot); mockFileSystem.AddFile(mockFileSystem.Path.Combine(globals.FileSystemOptions.FileSystemRoot, "file.dcm"), MockFileData.NullObject); var host = new FileCopierHost(globals, mockFileSystem); tester.StopOnDispose.Add(host); host.Start(); var message = new ExtractFileMessage { ExtractionJobIdentifier = Guid.NewGuid(), JobSubmittedAt = DateTime.UtcNow, ProjectNumber = "1234", ExtractionDirectory = "1234/foo", DicomFilePath = "file.dcm", IsIdentifiableExtraction = true, OutputPath = "output.dcm", }; tester.SendMessage(globals.FileCopierOptions, message); using IConnection conn = tester.Factory.CreateConnection(); using IModel model = conn.CreateModel(); var consumer = new EventingBasicConsumer(model); ExtractedFileStatusMessage statusMessage = null; consumer.Received += (_, ea) => statusMessage = JsonConvert.DeserializeObject <ExtractedFileStatusMessage>(Encoding.UTF8.GetString(ea.Body.ToArray())); model.BasicConsume(outputQueueName, true, "", consumer); new TestTimelineAwaiter().Await(() => statusMessage != null); Assert.AreEqual(ExtractedFileStatus.Copied, statusMessage.Status); }
public void TestLoadingOneImage_SingleFileMessage(int numberOfMessagesToSend, bool mixInATextFile) { _helper.TruncateTablesIfExists(); DirectoryInfo d = new DirectoryInfo(Path.Combine(TestContext.CurrentContext.TestDirectory, nameof(TestLoadingOneImage_SingleFileMessage))); d.Create(); var fi = TestData.Create(new FileInfo(Path.Combine(d.FullName, "MyTestFile.dcm"))); if (mixInATextFile) { var randomText = new FileInfo(Path.Combine(d.FullName, "RandomTextFile.dcm")); File.WriteAllLines(randomText.FullName, new[] { "I love dancing", "all around the world", "boy the world is a big place eh?" }); } //creates the queues, exchanges and bindings var tester = new MicroserviceTester(_globals.RabbitOptions, _globals.DicomRelationalMapperOptions); tester.CreateExchange(_globals.RabbitOptions.FatalLoggingExchange, null); using (var host = new DicomRelationalMapperHost(_globals)) { host.Start(); using (var timeline = new TestTimeline(tester)) { //send the message 10 times over a 10 second period for (int i = 0; i < numberOfMessagesToSend; i++) { timeline .SendMessage(_globals.DicomRelationalMapperOptions, _helper.GetDicomFileMessage(_globals.FileSystemOptions.FileSystemRoot, fi)) .Wait(1000); } //start the timeline timeline.StartTimeline(); Thread.Sleep(TimeSpan.FromSeconds(10)); new TestTimelineAwaiter().Await(() => host.Consumer.AckCount >= numberOfMessagesToSend, null, 30000, () => host.Consumer.DleErrors); Assert.AreEqual(1, _helper.SeriesTable.GetRowCount(), "SeriesTable did not have the expected number of rows in LIVE"); Assert.AreEqual(1, _helper.StudyTable.GetRowCount(), "StudyTable did not have the expected number of rows in LIVE"); Assert.AreEqual(1, _helper.ImageTable.GetRowCount(), "ImageTable did not have the expected number of rows in LIVE"); host.Stop("Test end"); } } tester.Shutdown(); }
public void IdenticalDatasetsTest() { _helper.TruncateTablesIfExists(); var ds = new DicomDataset(); ds.AddOrUpdate(DicomTag.SeriesInstanceUID, "123"); ds.AddOrUpdate(DicomTag.SOPInstanceUID, "123"); ds.AddOrUpdate(DicomTag.StudyInstanceUID, "123"); ds.AddOrUpdate(DicomTag.PatientID, "123"); var msg1 = _helper.GetDicomFileMessage(ds, _globals.FileSystemOptions.FileSystemRoot, Path.Combine(_globals.FileSystemOptions.FileSystemRoot, "mydicom.dcm")); var msg2 = _helper.GetDicomFileMessage(ds, _globals.FileSystemOptions.FileSystemRoot, Path.Combine(_globals.FileSystemOptions.FileSystemRoot, "mydicom.dcm")); //creates the queues, exchanges and bindings using (var tester = new MicroserviceTester(_globals.RabbitOptions, _globals.DicomRelationalMapperOptions)) { tester.CreateExchange(_globals.RabbitOptions.FatalLoggingExchange, null); tester.SendMessage(_globals.DicomRelationalMapperOptions, msg1); tester.SendMessage(_globals.DicomRelationalMapperOptions, msg2); _globals.DicomRelationalMapperOptions.RunChecks = true; using (var host = new DicomRelationalMapperHost(_globals)) { host.Start(); new TestTimelineAwaiter().Await(() => host.Consumer.MessagesProcessed == 2, null, 30000, () => host.Consumer.DleErrors); Assert.GreaterOrEqual(1, _helper.SeriesTable.GetRowCount(), "SeriesTable did not have the expected number of rows in LIVE"); Assert.GreaterOrEqual(1, _helper.StudyTable.GetRowCount(), "StudyTable did not have the expected number of rows in LIVE"); Assert.AreEqual(1, _helper.ImageTable.GetRowCount(), "ImageTable did not have the expected number of rows in LIVE"); host.Stop("Test end"); } tester.Shutdown(); } }
public void MapperSource_IntegrationTest(DatabaseType dbType) { var db = GetCleanedServer(dbType); DataTable dt = new DataTable(); dt.Columns.Add("PatientID", typeof(string)); dt.Columns.Add("StudyDescription", typeof(string)); dt.SetDoNotReType(true); // We have a live table with anonymised data. There is one person with a known ECHI 0101010101=0A0A0A0A0A dt.Rows.Add("0A0A0A0A0A", "CT Head"); //There are 2 people for whome we have added temporary identifiers dt.Rows.Add("bbb-bbb-bbb", "CT Tail"); dt.Rows.Add("ccc-ccc-ccc", "CT Wings"); var liveTable = db.CreateTable("MyLiveTable", dt); DiscoveredTable map; using (var dtMap = new DataTable()) { dtMap.Columns.Add("CHI"); dtMap.Columns.Add("ECHI"); dtMap.PrimaryKey = new [] { dtMap.Columns["CHI"] }; dtMap.Rows.Add("0101010101", "0A0A0A0A0A"); map = db.CreateTable("Map", dtMap); } // Import into RDMP the live table so we have a TableInfo pointer to it floating around Import(liveTable); var mapperOptions = new IdentifierMapperOptions() { MappingTableName = map.GetFullyQualifiedName(), MappingConnectionString = db.Server.Builder.ConnectionString, SwapColumnName = "CHI", ReplacementColumnName = "ECHI", MappingDatabaseType = db.Server.DatabaseType, SwapperType = typeof(TableLookupWithGuidFallbackSwapper).FullName }; var swapper = new TableLookupWithGuidFallbackSwapper(); swapper.Setup(mapperOptions); var guidTable = swapper.GetGuidTableIfAny(mapperOptions); Assert.AreEqual(0, guidTable.GetRowCount(), "No temporary guids should exist yet"); Assert.AreEqual(1, map.GetRowCount(), "We should have a mapping table with 1 entry"); guidTable.Insert(new Dictionary <string, object>() { { "CHI", "0202020202" }, { TableLookupWithGuidFallbackSwapper.GuidColumnName, "bbb-bbb-bbb" } }); guidTable.Insert(new Dictionary <string, object>() { { "CHI", "0303030303" }, { TableLookupWithGuidFallbackSwapper.GuidColumnName, "ccc-ccc-ccc" } }); Assert.AreEqual(1, map.GetRowCount(), "We should have a mapping table with 1 entry"); Assert.AreEqual(2, guidTable.GetRowCount(), "We should have a temporary guid for 0202020202"); // make a fake data load into this table (create trigger and insert/update) var triggerImplementer = new TriggerImplementerFactory(dbType).Create(map); triggerImplementer.CreateTrigger(new ThrowImmediatelyCheckNotifier()); //create a brand new mapping map.Insert(new Dictionary <string, object>() { { "CHI", "0303030303" }, { "ECHI", "0C0C0C0C0C" }, { SpecialFieldNames.ValidFrom, DateTime.Now }, { SpecialFieldNames.DataLoadRunID, 55 }, }); var globals = new GlobalOptionsFactory().Load(); var cliOptions = new TriggerUpdatesFromMapperOptions() { DateOfLastUpdate = new DateTime(2020, 01, 01), LiveDatabaseFieldName = "PatientID", Qualifier = '\'', }; globals.UseTestValues( RequiresRabbit.GetConnectionFactory(), RequiresMongoDb.GetMongoClientSettings(), RequiresRelationalDb.GetRelationalDatabaseConnectionStrings(), ((TableRepository)RepositoryLocator.CatalogueRepository).ConnectionStringBuilder, ((TableRepository)RepositoryLocator.DataExportRepository).ConnectionStringBuilder); //make sure the identifier mapper goes to the right table globals.IdentifierMapperOptions.MappingConnectionString = db.Server.Builder.ConnectionString; globals.IdentifierMapperOptions.MappingDatabaseType = dbType; globals.IdentifierMapperOptions.MappingTableName = map.GetFullyQualifiedName(); globals.IdentifierMapperOptions.SwapperType = typeof(TableLookupWithGuidFallbackSwapper).FullName; using (var tester = new MicroserviceTester(globals.RabbitOptions, globals.CohortExtractorOptions)) { tester.CreateExchange(globals.TriggerUpdatesOptions.ExchangeName, globals.UpdateValuesOptions.QueueName); var sourceHost = new TriggerUpdatesHost(globals, new MapperSource(globals, cliOptions)); var destHost = new UpdateValuesHost(globals); sourceHost.Start(); tester.StopOnDispose.Add(sourceHost); destHost.Start(); tester.StopOnDispose.Add(destHost); //wait till updater is done updating the live table new TestTimelineAwaiter().Await(() => destHost.Consumer.AckCount == 1); } var liveDtAfter = liveTable.GetDataTable(); Assert.AreEqual(1, liveDtAfter.Rows.Cast <DataRow>().Count(r => (string)r["PatientID"] == "0A0A0A0A0A"), "Expected original data to still be intact"); Assert.AreEqual(1, liveDtAfter.Rows.Cast <DataRow>().Count(r => (string)r["PatientID"] == "bbb-bbb-bbb"), "Expected unknown CHI with guid bbb to still be unknown"); Assert.AreEqual(1, liveDtAfter.Rows.Cast <DataRow>().Count(r => (string)r["PatientID"] == "0C0C0C0C0C"), "Expected the unknown CHI ccc to be now known as 0C0C0C0C0C"); }
public void TestIdentifierSwap_RegexVsDeserialize(DatabaseType type, int batchSize, int numberOfRandomTagsPerDicom) { var options = new GlobalOptionsFactory().Load(); var mappingDataTable = new DataTable("IdMap"); mappingDataTable.Columns.Add("priv"); mappingDataTable.Columns.Add("pub"); mappingDataTable.Rows.Add("010101", "020202"); mappingDataTable.Rows.Add("0101010101", "0202020202"); var db = GetCleanedServer(type); options.IdentifierMapperOptions.MappingConnectionString = db.Server.Builder.ConnectionString; options.IdentifierMapperOptions.MappingTableName = db.CreateTable("IdMap", mappingDataTable).GetFullyQualifiedName(); options.IdentifierMapperOptions.SwapColumnName = "priv"; options.IdentifierMapperOptions.ReplacementColumnName = "pub"; options.IdentifierMapperOptions.MappingDatabaseType = type; options.IdentifierMapperOptions.TimeoutInSeconds = 500; var swapper = new PreloadTableSwapper(); swapper.Setup(options.IdentifierMapperOptions); var goodChis = new List <DicomFileMessage>(); var badChis = new List <DicomFileMessage>(); Console.WriteLine("Generating Test data..."); List <Task> tasks = new List <Task>(); object oTaskLock = new object(); for (int i = 0; i < batchSize; i++) { var t = new Task(() => { var a = GetTestDicomFileMessage(Test.ProperlyFormatedChi, numberOfRandomTagsPerDicom); var b = GetTestDicomFileMessage(Test.ProperlyFormatedChi, numberOfRandomTagsPerDicom); lock (oTaskLock) { goodChis.Add(a); badChis.Add(b); } }); t.Start(); tasks.Add(t); if (i % Environment.ProcessorCount == 0) { Task.WaitAll(tasks.ToArray()); tasks.Clear(); } if (i % 100 == 0) { Console.WriteLine(i + " pairs done"); } } Task.WaitAll(tasks.ToArray()); options.IdentifierMapperOptions.AllowRegexMatching = true; using (var tester = new MicroserviceTester(options.RabbitOptions, options.IdentifierMapperOptions)) { tester.CreateExchange(options.IdentifierMapperOptions.AnonImagesProducerOptions.ExchangeName, null); Console.WriteLine("Pushing good messages to Rabbit..."); tester.SendMessages(options.IdentifierMapperOptions, goodChis, true); var host = new IdentifierMapperHost(options, swapper); tester.StopOnDispose.Add(host); Console.WriteLine("Starting host"); Stopwatch sw = Stopwatch.StartNew(); host.Start(); new TestTimelineAwaiter().Await(() => host.Consumer.AckCount == batchSize); Console.WriteLine("Good message processing (" + batchSize + ") took:" + sw.ElapsedMilliseconds + "ms"); host.Stop("Test finished"); } options.IdentifierMapperOptions.AllowRegexMatching = false; using (var tester = new MicroserviceTester(options.RabbitOptions, options.IdentifierMapperOptions)) { tester.CreateExchange(options.IdentifierMapperOptions.AnonImagesProducerOptions.ExchangeName, null); Console.WriteLine("Pushing bad messages to Rabbit..."); tester.SendMessages(options.IdentifierMapperOptions, badChis, true); var host = new IdentifierMapperHost(options, swapper); tester.StopOnDispose.Add(host); Console.WriteLine("Starting host"); Stopwatch sw = Stopwatch.StartNew(); host.Start(); new TestTimelineAwaiter().Await(() => host.Consumer.AckCount == batchSize); Console.WriteLine("Bad message processing (" + batchSize + ") took:" + sw.ElapsedMilliseconds + "ms"); host.Stop("Test finished"); } }
public void TestLoadingOneImage_MileWideTest() { _helper.TruncateTablesIfExists(); DirectoryInfo d = new DirectoryInfo(Path.Combine(TestContext.CurrentContext.TestDirectory, nameof(TestLoadingOneImage_MileWideTest))); d.Create(); var r = new Random(5000); FileInfo[] files; using (var g = new DicomDataGenerator(r, d, "CT")) files = g.GenerateImageFiles(1, r).ToArray(); Assert.AreEqual(1, files.Length); var existingColumns = _helper.ImageTable.DiscoverColumns(); //Add 200 random tags foreach (string tag in TagColumnAdder.GetAvailableTags().OrderBy(a => r.Next()).Take(200)) { string dataType; try { dataType = TagColumnAdder.GetDataTypeForTag(tag, new MicrosoftSQLTypeTranslater()); } catch (Exception) { continue; } if (existingColumns.Any(c => c.GetRuntimeName().Equals(tag))) { continue; } var adder = new TagColumnAdder(tag, dataType, _helper.ImageTableInfo, new AcceptAllCheckNotifier()); adder.SkipChecksAndSynchronization = true; adder.Execute(); } new TableInfoSynchronizer(_helper.ImageTableInfo).Synchronize(new AcceptAllCheckNotifier()); //creates the queues, exchanges and bindings var tester = new MicroserviceTester(_globals.RabbitOptions, _globals.DicomRelationalMapperOptions); tester.CreateExchange(_globals.RabbitOptions.FatalLoggingExchange, null); using (var host = new DicomRelationalMapperHost(_globals)) { host.Start(); using (var timeline = new TestTimeline(tester)) { foreach (var f in files) { timeline.SendMessage(_globals.DicomRelationalMapperOptions, _helper.GetDicomFileMessage(_globals.FileSystemOptions.FileSystemRoot, f)); } //start the timeline timeline.StartTimeline(); new TestTimelineAwaiter().Await(() => host.Consumer.MessagesProcessed == 1, null, 30000, () => host.Consumer.DleErrors); Assert.GreaterOrEqual(1, _helper.SeriesTable.GetRowCount(), "SeriesTable did not have the expected number of rows in LIVE"); Assert.GreaterOrEqual(1, _helper.StudyTable.GetRowCount(), "StudyTable did not have the expected number of rows in LIVE"); Assert.AreEqual(1, _helper.ImageTable.GetRowCount(), "ImageTable did not have the expected number of rows in LIVE"); host.Stop("Test end"); } } tester.Shutdown(); }
private void RunTest(DirectoryInfo dir, int numberOfExpectedRows, Action <FileSystemOptions> adjustFileSystemOptions) { TestLogger.Setup(); var logger = LogManager.GetLogger("MicroservicesIntegrationTest"); _globals.FileSystemOptions.FileSystemRoot = TestContext.CurrentContext.TestDirectory; var readFromFatalErrors = new ConsumerOptions { QueueName = "TEST.FatalLoggingQueue" }; ///////////////////////////////////// Directory ////////////////////////// var processDirectoryOptions = new DicomDirectoryProcessorCliOptions(); processDirectoryOptions.ToProcessDir = dir; processDirectoryOptions.DirectoryFormat = "Default"; adjustFileSystemOptions?.Invoke(_globals.FileSystemOptions); //////////////////////////////////////////////// Mongo Db Populator //////////////////////// // Make this a GUID or something, should be unique per test var currentSeriesCollectionName = "Integration_HappyPath_Series" + DateTime.Now.Ticks; var currentImageCollectionName = "Integration_HappyPath_Image" + DateTime.Now.Ticks; _globals.MongoDbPopulatorOptions.SeriesCollection = currentSeriesCollectionName; _globals.MongoDbPopulatorOptions.ImageCollection = currentImageCollectionName; //use the test catalogue not the one in the combined app.config _globals.RDMPOptions.CatalogueConnectionString = ((TableRepository)RepositoryLocator.CatalogueRepository).DiscoveredServer.Builder.ConnectionString; _globals.RDMPOptions.DataExportConnectionString = ((TableRepository)RepositoryLocator.DataExportRepository).DiscoveredServer.Builder.ConnectionString; _globals.DicomRelationalMapperOptions.RunChecks = true; if (_globals.DicomRelationalMapperOptions.MinimumBatchSize < 1) { _globals.DicomRelationalMapperOptions.MinimumBatchSize = 1; } using (var tester = new MicroserviceTester(_globals.RabbitOptions, _globals.CohortExtractorOptions)) { tester.CreateExchange(_globals.ProcessDirectoryOptions.AccessionDirectoryProducerOptions.ExchangeName, _globals.DicomTagReaderOptions.QueueName); tester.CreateExchange(_globals.DicomTagReaderOptions.SeriesProducerOptions.ExchangeName, _globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions.QueueName); tester.CreateExchange(_globals.DicomTagReaderOptions.ImageProducerOptions.ExchangeName, _globals.IdentifierMapperOptions.QueueName); tester.CreateExchange(_globals.DicomTagReaderOptions.ImageProducerOptions.ExchangeName, _globals.MongoDbPopulatorOptions.ImageQueueConsumerOptions.QueueName, true); tester.CreateExchange(_globals.IdentifierMapperOptions.AnonImagesProducerOptions.ExchangeName, _globals.DicomRelationalMapperOptions.QueueName); tester.CreateExchange(_globals.RabbitOptions.FatalLoggingExchange, readFromFatalErrors.QueueName); tester.CreateExchange(_globals.CohortExtractorOptions.ExtractFilesProducerOptions.ExchangeName, null, false, _globals.CohortExtractorOptions.ExtractIdentRoutingKey); tester.CreateExchange(_globals.CohortExtractorOptions.ExtractFilesProducerOptions.ExchangeName, null, true, _globals.CohortExtractorOptions.ExtractAnonRoutingKey); tester.CreateExchange(_globals.CohortExtractorOptions.ExtractFilesInfoProducerOptions.ExchangeName, null); #region Running Microservices var processDirectory = new DicomDirectoryProcessorHost(_globals, processDirectoryOptions); processDirectory.Start(); tester.StopOnDispose.Add(processDirectory); var dicomTagReaderHost = new DicomTagReaderHost(_globals); dicomTagReaderHost.Start(); tester.StopOnDispose.Add(dicomTagReaderHost); var mongoDbPopulatorHost = new MongoDbPopulatorHost(_globals); mongoDbPopulatorHost.Start(); tester.StopOnDispose.Add(mongoDbPopulatorHost); var identifierMapperHost = new IdentifierMapperHost(_globals, new SwapForFixedValueTester("FISHFISH")); identifierMapperHost.Start(); tester.StopOnDispose.Add(identifierMapperHost); new TestTimelineAwaiter().Await(() => dicomTagReaderHost.AccessionDirectoryMessageConsumer.AckCount >= 1); logger.Info("\n### DicomTagReader has processed its messages ###\n"); // FIXME: This isn't exactly how the pipeline runs new TestTimelineAwaiter().Await(() => identifierMapperHost.Consumer.AckCount >= 1); logger.Info("\n### IdentifierMapper has processed its messages ###\n"); using (var relationalMapperHost = new DicomRelationalMapperHost(_globals)) { var start = DateTime.Now; relationalMapperHost.Start(); tester.StopOnDispose.Add(relationalMapperHost); Assert.True(mongoDbPopulatorHost.Consumers.Count == 2); new TestTimelineAwaiter().Await(() => mongoDbPopulatorHost.Consumers[0].Processor.AckCount >= 1); new TestTimelineAwaiter().Await(() => mongoDbPopulatorHost.Consumers[1].Processor.AckCount >= 1); logger.Info("\n### MongoDbPopulator has processed its messages ###\n"); new TestTimelineAwaiter().Await(() => identifierMapperHost.Consumer.AckCount >= 1);//number of series logger.Info("\n### IdentifierMapper has processed its messages ###\n"); Assert.AreEqual(0, dicomTagReaderHost.AccessionDirectoryMessageConsumer.NackCount); Assert.AreEqual(0, identifierMapperHost.Consumer.NackCount); Assert.AreEqual(0, ((Consumer <SeriesMessage>)mongoDbPopulatorHost.Consumers[0]).NackCount); Assert.AreEqual(0, ((Consumer <DicomFileMessage>)mongoDbPopulatorHost.Consumers[1]).NackCount); try { Thread.Sleep(TimeSpan.FromSeconds(10)); new TestTimelineAwaiter().Await(() => relationalMapperHost.Consumer.AckCount >= numberOfExpectedRows, null, 30000, () => relationalMapperHost.Consumer.DleErrors); //number of image files logger.Info("\n### DicomRelationalMapper has processed its messages ###\n"); } finally { //find out what happens from the logging database var rdmpLogging = new Rdmp.Core.Logging.LogManager(_helper.LoadMetadata.GetDistinctLoggingDatabase()); //if error was reported during the dicom relational mapper run foreach (var dli in rdmpLogging.GetArchivalDataLoadInfos(_helper.LoadMetadata.GetDistinctLoggingTask(), null, null)) { if (dli.StartTime > start) { foreach (ArchivalFatalError e in dli.Errors) { logger.Error(e.Date.TimeOfDay + ":" + e.Source + ":" + e.Description); } } } } Assert.AreEqual(numberOfExpectedRows, _helper.ImageTable.GetRowCount(), "All images should appear in the image table"); Assert.LessOrEqual(_helper.SeriesTable.GetRowCount(), numberOfExpectedRows, "Only unique series data should appear in series table, there should be less unique series than images (or equal)"); Assert.LessOrEqual(_helper.StudyTable.GetRowCount(), numberOfExpectedRows, "Only unique study data should appear in study table, there should be less unique studies than images (or equal)"); Assert.LessOrEqual(_helper.StudyTable.GetRowCount(), _helper.SeriesTable.GetRowCount(), "There should be less studies than series (or equal)"); //make sure that the substitution identifier (that replaces old the PatientId) is the correct substitution (FISHFISH)/ Assert.AreEqual("FISHFISH", _helper.StudyTable.GetDataTable().Rows.OfType <DataRow>().First()["PatientId"]); //The file size in the final table should be more than 0 Assert.Greater((long)_helper.ImageTable.GetDataTable().Rows.OfType <DataRow>().First()["DicomFileSize"], 0); dicomTagReaderHost.Stop("TestIsFinished"); mongoDbPopulatorHost.Stop("TestIsFinished"); DropMongoTestDb(_globals.MongoDatabases.DicomStoreOptions.HostName, _globals.MongoDatabases.DicomStoreOptions.Port); identifierMapperHost.Stop("TestIsFinished"); relationalMapperHost.Stop("Test end"); } //Now do extraction var extractorHost = new CohortExtractorHost(_globals, null, null); extractorHost.Start(); var extract = new ExtractionRequestMessage { ExtractionJobIdentifier = Guid.NewGuid(), ProjectNumber = "1234-5678", ExtractionDirectory = "1234-5678_P1", KeyTag = "SeriesInstanceUID", }; foreach (DataRow row in _helper.ImageTable.GetDataTable().Rows) { var ser = (string)row["SeriesInstanceUID"]; if (!extract.ExtractionIdentifiers.Contains(ser)) { extract.ExtractionIdentifiers.Add(ser); } } tester.SendMessage(_globals.CohortExtractorOptions, extract); //wait till extractor picked up the messages and dispatched the responses new TestTimelineAwaiter().Await(() => extractorHost.Consumer.AckCount == 1); extractorHost.Stop("TestIsFinished"); tester.Shutdown(); } #endregion }