コード例 #1
0
        public void TestPersistMessageToStore_IsIdentifiableMessage()
        {
            var testExtractJobStore = new TestExtractJobStore();
            var header = new MessageHeader();

            // Must have AnonymisedFileName
            var message = new ExtractedFileVerificationMessage();

            message.OutputFilePath = "";
            Assert.Throws <ApplicationException>(() => testExtractJobStore.PersistMessageToStore(message, header));

            // Report shouldn't be an empty string or null
            message = new ExtractedFileVerificationMessage();
            message.OutputFilePath = "anon.dcm";
            message.Report         = "";
            Assert.Throws <ApplicationException>(() => testExtractJobStore.PersistMessageToStore(message, header));

            // Report needs to contain content if marked as IsIdentifiable
            message = new ExtractedFileVerificationMessage();
            message.OutputFilePath = "anon.dcm";
            message.IsIdentifiable = true;
            message.Report         = "[]";
            Assert.Throws <ApplicationException>(() => testExtractJobStore.PersistMessageToStore(message, header));
            // NOTE(rkm 2020-07-23) The actual report content is verified to be valid the message consumer, so don't need to re-check here
            message.Report = "['foo': 'bar']";
            testExtractJobStore.PersistMessageToStore(message, header);

            // Report can be empty if not marked as IsIdentifiable
            message = new ExtractedFileVerificationMessage();
            message.OutputFilePath = "anon.dcm";
            message.IsIdentifiable = false;
            message.Report         = "[]";
            testExtractJobStore.PersistMessageToStore(message, header);
        }
コード例 #2
0
        public void Integration_HappyPath(ReportFormat reportFormat)
        {
            // Test messages:
            //  - series-1
            //      - series-1-anon-1.dcm -> valid

            using var pf = new PathFixtures($"Integration_HappyPath_{reportFormat}");

            var jobId = Guid.NewGuid();
            var testExtractionRequestInfoMessage = new ExtractionRequestInfoMessage
            {
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                ProjectNumber           = "testProj1",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = pf.ProjExtractDirRelative,
                KeyTag        = "SeriesInstanceUID",
                KeyValueCount = 1,
            };
            var testExtractFileCollectionInfoMessage = new ExtractFileCollectionInfoMessage
            {
                JobSubmittedAt                = _dateTimeProvider.UtcNow(),
                ProjectNumber                 = "testProj1",
                ExtractionJobIdentifier       = jobId,
                ExtractionDirectory           = pf.ProjExtractDirRelative,
                ExtractFileMessagesDispatched = new JsonCompatibleDictionary <MessageHeader, string>
                {
                    { new MessageHeader(), "series-1-anon-1.dcm" },
                },
                RejectionReasons = new Dictionary <string, int>
                {
                    { "rejected - blah", 1 },
                },
                KeyValue = "series-1",
            };
            var testIsIdentifiableMessage = new ExtractedFileVerificationMessage
            {
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                OutputFilePath          = "series-1-anon-1.dcm",
                ProjectNumber           = "testProj1",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = pf.ProjExtractDirRelative,
                IsIdentifiable          = false,
                Report        = "[]",
                DicomFilePath = "series-1-orig-1.dcm",
            };

            GlobalOptions globals = new GlobalOptionsFactory().Load();

            VerifyReports(
                globals,
                pf,
                reportFormat,
                new[]
            {
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.ExtractRequestInfoOptions, testExtractionRequestInfoMessage),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.FileCollectionInfoOptions, testExtractFileCollectionInfoMessage),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.VerificationStatusOptions, testIsIdentifiableMessage),
            }
                );
        }
コード例 #3
0
        public void PersistMessageToStore(
            [NotNull] ExtractedFileVerificationMessage message,
            [NotNull] IMessageHeader header)
        {
            if (string.IsNullOrWhiteSpace(message.OutputFilePath))
            {
                throw new ApplicationException("Received a verification message without the AnonymisedFileName set");
            }
            if (string.IsNullOrWhiteSpace(message.Report))
            {
                throw new ApplicationException("Null or empty report data");
            }
            if (message.IsIdentifiable && message.Report == "[]")
            {
                throw new ApplicationException("No report data for message marked as identifiable");
            }

            PersistMessageToStoreImpl(message, header);
        }
コード例 #4
0
        protected override void PersistMessageToStoreImpl(ExtractedFileVerificationMessage message, IMessageHeader header)
        {
            if (InCompletedJobCollection(message.ExtractionJobIdentifier))
            {
                throw new ApplicationException("Received an ExtractedFileVerificationMessage for a job that is already completed");
            }

            var newStatus = new MongoFileStatusDoc(
                MongoExtractionMessageHeaderDoc.FromMessageHeader(message.ExtractionJobIdentifier, header, _dateTimeProvider),
                message.DicomFilePath,
                message.OutputFilePath,
                wasAnonymised: true,
                isIdentifiable: message.IsIdentifiable,
                ExtractedFileStatus.Anonymised,
                statusMessage: message.Report);

            _database
            .GetCollection <MongoFileStatusDoc>(StatusCollectionName(message.ExtractionJobIdentifier))
            .InsertOne(newStatus);
        }
コード例 #5
0
        public void TestPersistMessageToStoreImpl_IsIdentifiableMessage()
        {
            var client = new TestMongoClient();
            var store  = new MongoExtractJobStore(client, ExtractionDatabaseName, _dateTimeProvider);

            Guid jobId = Guid.NewGuid();
            var  testIsIdentifiableMessage = new ExtractedFileVerificationMessage
            {
                OutputFilePath          = "anon.dcm",
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                ProjectNumber           = "1234",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = "1234/test",
                DicomFilePath           = "original.dcm",
                IsIdentifiable          = false,
                Report = "[]", // NOTE(rkm 2020-03-10) An "empty" report from IsIdentifiable
            };
            var header = new MessageHeader();

            store.PersistMessageToStore(testIsIdentifiableMessage, header);

            Dictionary <Guid, MongoFileStatusDoc> docs = client.ExtractionDatabase.StatusCollections[$"statuses_{jobId}"].Documents;

            Assert.AreEqual(docs.Count, 1);
            MongoFileStatusDoc statusDoc = docs.Values.ToList()[0];

            var expected = new MongoFileStatusDoc(
                MongoExtractionMessageHeaderDoc.FromMessageHeader(jobId, header, _dateTimeProvider),
                "original.dcm",
                "anon.dcm",
                true,
                false,
                ExtractedFileStatus.Anonymised,
                "[]");

            Assert.True(statusDoc.Equals(expected));
        }
コード例 #6
0
        public void Integration_BumpyRoad(ReportFormat reportFormat)
        {
            // Test messages:
            //  - series-1
            //      - series-1-anon-1.dcm -> valid
            //      - series-1-anon-2.dcm -> rejected
            //  - series-2
            //      - series-2-anon-1.dcm -> fails anonymisation
            //      - series-2-anon-2.dcm -> fails validation

            using var pf = new PathFixtures($"Integration_BumpyRoad_{reportFormat}");

            var jobId = Guid.NewGuid();
            var testExtractionRequestInfoMessage = new ExtractionRequestInfoMessage
            {
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                ProjectNumber           = "testProj1",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = pf.ProjExtractDirRelative,
                KeyTag        = "SeriesInstanceUID",
                KeyValueCount = 2,
            };
            var testExtractFileCollectionInfoMessage1 = new ExtractFileCollectionInfoMessage
            {
                JobSubmittedAt                = _dateTimeProvider.UtcNow(),
                ProjectNumber                 = "testProj1",
                ExtractionJobIdentifier       = jobId,
                ExtractionDirectory           = pf.ProjExtractDirRelative,
                ExtractFileMessagesDispatched = new JsonCompatibleDictionary <MessageHeader, string>
                {
                    { new MessageHeader(), "series-1-anon-1.dcm" },
                },
                RejectionReasons = new Dictionary <string, int>
                {
                    { "rejected - blah", 1 },
                },
                KeyValue = "series-1",
            };
            var testExtractFileCollectionInfoMessage2 = new ExtractFileCollectionInfoMessage
            {
                JobSubmittedAt                = _dateTimeProvider.UtcNow(),
                ProjectNumber                 = "testProj1",
                ExtractionJobIdentifier       = jobId,
                ExtractionDirectory           = pf.ProjExtractDirRelative,
                ExtractFileMessagesDispatched = new JsonCompatibleDictionary <MessageHeader, string>
                {
                    { new MessageHeader(), "series-2-anon-1.dcm" },
                    { new MessageHeader(), "series-2-anon-2.dcm" },
                },
                RejectionReasons = new Dictionary <string, int>(),
                KeyValue         = "series-2",
            };
            var testExtractFileStatusMessage = new ExtractedFileStatusMessage
            {
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                OutputFilePath          = "series-2-anon-1.dcm",
                ProjectNumber           = "testProj1",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = pf.ProjExtractDirRelative,
                Status        = ExtractedFileStatus.ErrorWontRetry,
                StatusMessage = "Couldn't anonymise",
                DicomFilePath = "series-2-orig-1.dcm",
            };
            var testIsIdentifiableMessage1 = new ExtractedFileVerificationMessage
            {
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                OutputFilePath          = "series-1-anon-1.dcm",
                ProjectNumber           = "testProj1",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = pf.ProjExtractDirRelative,
                IsIdentifiable          = false,
                Report        = "[]",
                DicomFilePath = "series-1-orig-1.dcm",
            };
            const string failureReport = @"
[
    {
        'Parts': [],
        'Resource': 'series-2-anon-2.dcm',
        'ResourcePrimaryKey': '1.2.3.4',
        'ProblemField': 'ScanOptions',
        'ProblemValue': 'FOO'
    }
]";
            var          testIsIdentifiableMessage2 = new ExtractedFileVerificationMessage
            {
                JobSubmittedAt          = _dateTimeProvider.UtcNow(),
                OutputFilePath          = "series-2-anon-2.dcm",
                ProjectNumber           = "testProj1",
                ExtractionJobIdentifier = jobId,
                ExtractionDirectory     = pf.ProjExtractDirRelative,
                IsIdentifiable          = true,
                Report        = failureReport,
                DicomFilePath = "series-2-orig-2.dcm",
            };

            GlobalOptions globals = new GlobalOptionsFactory().Load();

            VerifyReports(
                globals,
                pf,
                reportFormat,
                new[]
            {
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.ExtractRequestInfoOptions, testExtractionRequestInfoMessage),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.FileCollectionInfoOptions, testExtractFileCollectionInfoMessage1),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.FileCollectionInfoOptions, testExtractFileCollectionInfoMessage2),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.NoVerifyStatusOptions, testExtractFileStatusMessage),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.VerificationStatusOptions, testIsIdentifiableMessage1),
                new Tuple <ConsumerOptions, IMessage>(globals.CohortPackagerOptions.VerificationStatusOptions, testIsIdentifiableMessage2),
            }
                );
        }
コード例 #7
0
 protected override void PersistMessageToStoreImpl(ExtractedFileVerificationMessage message, IMessageHeader header)
 {
 }
コード例 #8
0
 protected abstract void PersistMessageToStoreImpl(ExtractedFileVerificationMessage message, IMessageHeader header);