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()); }
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); }
/// <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 } }); }
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 }; }
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); }
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); }
/// <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(); } }
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(); } }