Пример #1
0
        public void TestEquals_SeriesMessage()
        {
            var msg1 = new SeriesMessage();
            var msg2 = new SeriesMessage();

            Assert.AreEqual(msg1, msg2);
            Assert.AreEqual(msg1.GetHashCode(), msg2.GetHashCode());

            msg1.NationalPACSAccessionNumber = "500";
            msg2.NationalPACSAccessionNumber = "500";

            Assert.AreEqual(msg1, msg2);
            Assert.AreEqual(msg1.GetHashCode(), msg2.GetHashCode());

            msg1.NationalPACSAccessionNumber = "999";
            Assert.AreNotEqual(msg1, msg2);
            Assert.AreNotEqual(msg1.GetHashCode(), msg2.GetHashCode());

            msg1.NationalPACSAccessionNumber = "500";

            msg1.DicomDataset = "jsonified string";
            msg2.DicomDataset = "jsonified string";

            Assert.AreEqual(msg1, msg2);
            Assert.AreEqual(msg1.GetHashCode(), msg2.GetHashCode());
        }
Пример #2
0
        private void Validate(SeriesMessage message, BsonDocument document)
        {
            Assert.False(message == null || document == null);

            BsonElement element;

            Assert.True(document.TryGetElement("header", out element));

            var docHeader = (BsonDocument)element.Value;

            Assert.AreEqual(_seriesMessageProps.Count - 3, docHeader.ElementCount);
            Assert.AreEqual(message.DirectoryPath, docHeader["DirectoryPath"].AsString);
            Assert.AreEqual(message.NationalPACSAccessionNumber, docHeader["NationalPACSAccessionNumber"].AsString);
            Assert.AreEqual(message.ImagesInSeries, docHeader["ImagesInSeries"].AsInt32);

            DicomDataset dataset = DicomTypeTranslater.DeserializeJsonToDataset(message.DicomDataset);

            Assert.NotNull(dataset);

            BsonDocument datasetDocument = DicomTypeTranslaterReader.BuildBsonDocument(dataset);

            document.Remove("_id");
            document.Remove("header");

            Assert.AreEqual(datasetDocument, document);
        }
Пример #3
0
 /// <summary>
 /// Generate a header for a series document
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 public static BsonDocument SeriesDocumentHeader(SeriesMessage message)
 {
     return(new BsonDocument
     {
         { "DirectoryPath", message.DirectoryPath },
         { "NationalPACSAccessionNumber", AccessionNoOrNull(message.NationalPACSAccessionNumber) },
         { "ImagesInSeries", message.ImagesInSeries }
     });
 }
Пример #4
0
        public void SetupSuite()
        {
            Globals = GetNewMongoDbPopulatorOptions();

            _mongoTestClient = MongoClientHelpers.GetMongoClient(Globals.MongoDatabases.DicomStoreOptions, "MongoDbPopulatorTests");

            _mongoTestClient.DropDatabase(TestDbName);
            TestDatabase = _mongoTestClient.GetDatabase(TestDbName);

            Globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions = new ConsumerOptions()
            {
                QueueName        = "TEST.SeriesQueue",
                QoSPrefetchCount = 5,
                AutoAck          = false
            };

            Globals.MongoDbPopulatorOptions.ImageQueueConsumerOptions = new ConsumerOptions()
            {
                QueueName        = "TEST.MongoImageQueue",
                QoSPrefetchCount = 50,
                AutoAck          = false
            };

            var dataset = new DicomDataset
            {
                new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, "1.2.3.4"),
                new DicomCodeString(DicomTag.Modality, "SR")
            };

            string serialized = DicomTypeTranslater.SerializeDatasetToJson(dataset);

            TestImageMessage = new DicomFileMessage
            {
                DicomFilePath = "Path/To/File",
                NationalPACSAccessionNumber = "123",
                SeriesInstanceUID           = "TestSeriesInstanceUID",
                StudyInstanceUID            = "TestStudyInstanceUID",
                SOPInstanceUID = "TestSOPInstanceUID",
                DicomDataset   = serialized
            };

            TestSeriesMessage = new SeriesMessage
            {
                DirectoryPath  = "Path/To/Series",
                ImagesInSeries = 123,
                NationalPACSAccessionNumber = "123",
                SeriesInstanceUID           = "TestSeriesInstanceUID",
                StudyInstanceUID            = "TestStudyInstanceUID",
                DicomDataset = serialized
            };
        }
Пример #5
0
        public void SeriesDocumentHeader_HasCorrectHeaders()
        {
            var msg = new SeriesMessage
            {
                DirectoryPath = "path/to/files",
                NationalPACSAccessionNumber = "AAA",
                ImagesInSeries = 1234
            };

            BsonDocument seriesHeader = MongoDocumentHeaders.SeriesDocumentHeader(msg);

            var expected = new BsonDocument
            {
                { "DirectoryPath", msg.DirectoryPath },
                { "NationalPACSAccessionNumber", msg.NationalPACSAccessionNumber },
                { "ImagesInSeries", msg.ImagesInSeries }
            };

            Assert.AreEqual(expected, seriesHeader);
        }
Пример #6
0
        public void Test_SeriesDocumentHeader_NullAccessionNo()
        {
            var msg = new SeriesMessage
            {
                DirectoryPath = "path/to/files",
                NationalPACSAccessionNumber = null,
                ImagesInSeries = 1234
            };

            BsonDocument seriesHeader = MongoDocumentHeaders.SeriesDocumentHeader(msg);

            var expected = new BsonDocument
            {
                { "DirectoryPath", msg.DirectoryPath },
                { "NationalPACSAccessionNumber", BsonNull.Value },
                { "ImagesInSeries", msg.ImagesInSeries }
            };

            Assert.AreEqual(expected, seriesHeader);
        }
Пример #7
0
        /// <summary>
        /// Process files from the directory referenced in the message
        /// </summary>
        /// <param name="header"></param>
        /// <param name="message"></param>
        public void ReadTags(IMessageHeader header, AccessionDirectoryMessage message)
        {
            _stopwatch.Restart();

            string dirPath = message.GetAbsolutePath(_filesystemRoot);

            Logger.Debug("TagReader: About to process files in " + dirPath);

            if (!_fs.Directory.Exists(dirPath))
            {
                throw new ApplicationException("Directory not found: " + dirPath);
            }

            if (!dirPath.StartsWith(_filesystemRoot, StringComparison.CurrentCultureIgnoreCase))
            {
                throw new ApplicationException("Directory " + dirPath + " is not below the given FileSystemRoot (" +
                                               _filesystemRoot + ")");
            }
            long beginEnumerate = _stopwatch.ElapsedTicks;

            string[] dicomFilePaths = _fs.Directory.EnumerateFiles(dirPath, _searchPattern).Where(Include).ToArray();
            string[] zipFilePaths   = _fs.Directory.EnumerateFiles(dirPath).Where(ZipHelper.IsZip).Where(Include).ToArray();

            _swTotals[0] += _stopwatch.ElapsedTicks - beginEnumerate;
            Logger.Debug("TagReader: Found " + dicomFilePaths.Length + " dicom files to process");
            Logger.Debug("TagReader: Found " + zipFilePaths.Length + " zip files to process");

            int toProcess = dicomFilePaths.Length + zipFilePaths.Length;

            if (toProcess == 0)
            {
                throw new ApplicationException("No dicom/zip files found in " + dirPath);
            }

            // We have files to process, let's do it!

            long beginRead = _stopwatch.ElapsedTicks;

            List <DicomFileMessage> fileMessages = ReadTagsImpl(dicomFilePaths.Select(p => new FileInfo(p)), message);

            fileMessages.AddRange(ReadZipFilesImpl(zipFilePaths.Select(p => new FileInfo(p)), message));

            _swTotals[1] += (_stopwatch.ElapsedTicks - beginRead) / toProcess;

            var seriesMessages = new Dictionary <string, SeriesMessage>();

            foreach (DicomFileMessage fileMessage in fileMessages)
            {
                string seriesUID = fileMessage.SeriesInstanceUID;

                // If we've already seen this seriesUID, just update the image count
                if (seriesMessages.ContainsKey(seriesUID))
                {
                    seriesMessages[seriesUID].ImagesInSeries++;
                    continue;
                }

                // Else create a new SeriesMessage
                var seriesMessage = new SeriesMessage
                {
                    NationalPACSAccessionNumber = fileMessage.NationalPACSAccessionNumber,
                    DirectoryPath = message.DirectoryPath,

                    StudyInstanceUID  = fileMessage.StudyInstanceUID,
                    SeriesInstanceUID = seriesUID,

                    ImagesInSeries = 1,

                    DicomDataset = fileMessage.DicomDataset
                };

                seriesMessages.Add(seriesUID, seriesMessage);
            }

            Logger.Debug("TagReader: Finished processing directory, sending messages");

            // Only send if have processed all files in the directory ok

            if (!fileMessages.Any())
            {
                throw new ApplicationException("No DicomFileMessage(s) to send after processing the directory");
            }

            if (!seriesMessages.Any())
            {
                throw new ApplicationException("No SeriesMessage(s) to send but we have file messages");
            }

            Logger.Info($"Sending {fileMessages.Count} DicomFileMessage(s)");

            long beginSend = _stopwatch.ElapsedTicks;
            var  headers   = new List <IMessageHeader>();

            foreach (DicomFileMessage fileMessage in fileMessages)
            {
                headers.Add(_fileMessageProducerModel.SendMessage(fileMessage, header));
            }

            _fileMessageProducerModel.WaitForConfirms();

            headers.ForEach(x => x.Log(Logger, LogLevel.Trace, $"Sent {header?.MessageGuid}"));

            Logger.Info($"Sending {seriesMessages.Count} SeriesMessage(s)");

            headers.Clear();
            foreach (KeyValuePair <string, SeriesMessage> kvp in seriesMessages)
            {
                headers.Add(_seriesMessageProducerModel.SendMessage(kvp.Value, header));
            }

            _seriesMessageProducerModel.WaitForConfirms();
            headers.ForEach(x => x.Log(Logger, LogLevel.Trace, $"Sent {x.MessageGuid}"));

            _swTotals[2]   += _stopwatch.ElapsedTicks - beginSend;
            _swTotals[3]   += _stopwatch.ElapsedTicks;
            _nMessagesSent += fileMessages.Count + seriesMessages.Count;

            if (++_nAccMessagesProcessed % 10 == 0)
            {
                LogRates();
            }
        }
Пример #8
0
        public void TestPopulatorBasic(int nMessages)
        {
            // Arrange

            string currentCollectionName = MongoDbPopulatorTestHelper.GetCollectionNameForTest(string.Format("TestPopulatorBasic({0})", nMessages));

            _helper.Globals.MongoDbPopulatorOptions.SeriesCollection = currentCollectionName;

            var tester = new MicroserviceTester(_helper.Globals.RabbitOptions, _helper.Globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions, _helper.Globals.MongoDbPopulatorOptions.ImageQueueConsumerOptions);
            var host   = new MongoDbPopulatorHost(_helper.Globals);

            host.Start();

            using (var timeline = new TestTimeline(tester))
            {
                var ds = new DicomDataset
                {
                    new DicomUniqueIdentifier(DicomTag.SOPInstanceUID, "1.2.3.4")
                };

                var message = new SeriesMessage
                {
                    NationalPACSAccessionNumber = "NationalPACSAccessionNumber-test",
                    DirectoryPath     = "DirectoryPath-test",
                    StudyInstanceUID  = "StudyInstanceUID-test",
                    SeriesInstanceUID = "SeriesInstanceUID-test",
                    ImagesInSeries    = 123,
                    DicomDataset      = DicomTypeTranslater.SerializeDatasetToJson(ds)
                };

                // Act

                for (var i = 0; i < nMessages; i++)
                {
                    timeline.SendMessage(_helper.Globals.MongoDbPopulatorOptions.SeriesQueueConsumerOptions, message);
                }

                timeline.StartTimeline();

                var       timeout  = 30000;
                const int stepSize = 500;

                if (Debugger.IsAttached)
                {
                    timeout = int.MaxValue;
                }

                var nWritten = 0L;

                while (nWritten < nMessages && timeout > 0)
                {
                    nWritten = _helper.TestDatabase.GetCollection <BsonDocument>(currentCollectionName).CountDocuments(new BsonDocument());

                    Thread.Sleep(stepSize);
                    timeout -= stepSize;
                }

                // Assert

                if (timeout <= 0)
                {
                    Assert.Fail("Failed to process expected number of messages within the timeout");
                }

                host.Stop("Test end");
                tester.Shutdown();
            }
        }