Exemple #1
0
        public async Task GivenNonExistingExtendedQueryTag_WhenDeleteExtendedQueryTag_ThenShouldThrowException()
        {
            DicomTag tag = DicomTag.DeviceSerialNumber;
            GetExtendedQueryTagEntry extendedQueryTagEntry = tag.BuildGetExtendedQueryTagEntry();
            await Assert.ThrowsAsync <ExtendedQueryTagNotFoundException>(() => _extendedQueryTagStore.DeleteExtendedQueryTagAsync(extendedQueryTagEntry.Path, extendedQueryTagEntry.VR));

            await VerifyTagNotExistAsync(extendedQueryTagEntry.Path);
        }
Exemple #2
0
        public async Task GivenValidExtendedQueryTags_WhenGoThroughEndToEndScenario_ThenShouldSucceed()
        {
            // Prepare 3 extended query tags.
            // One is private tag on Instance level
            // To add private tag, need to add identification code element at first.
            DicomTag identificationCodeTag = new DicomTag(0x0407, 0x0010);

            DicomElement identificationCodeElement = new DicomLongString(identificationCodeTag, PrivateCreatorName);

            DicomTag privateTag = new DicomTag(0x0407, 0x1001, PrivateCreatorName);
            AddExtendedQueryTagEntry privateQueryTag = new AddExtendedQueryTagEntry {
                Path = privateTag.GetPath(), VR = DicomVRCode.SS, Level = QueryTagLevel.Instance, PrivateCreator = privateTag.PrivateCreator.Creator
            };

            // One is standard tag on Series level
            DicomTag standardTagSeries = DicomTag.ManufacturerModelName;
            AddExtendedQueryTagEntry standardTagSeriesQueryTag = new AddExtendedQueryTagEntry {
                Path = standardTagSeries.GetPath(), VR = standardTagSeries.GetDefaultVR().Code, Level = QueryTagLevel.Series
            };

            // One is standard tag on Study level
            DicomTag standardTagStudy = DicomTag.PatientSex;
            AddExtendedQueryTagEntry standardTagStudyQueryTag = new AddExtendedQueryTagEntry {
                Path = standardTagStudy.GetPath(), VR = standardTagStudy.GetDefaultVR().Code, Level = QueryTagLevel.Study
            };

            AddExtendedQueryTagEntry[] queryTags = new AddExtendedQueryTagEntry[] { privateQueryTag, standardTagSeriesQueryTag, standardTagStudyQueryTag };

            // Create 3 test files on same studyUid.
            string studyUid     = TestUidGenerator.Generate();
            string seriesUid1   = TestUidGenerator.Generate();
            string seriesUid2   = TestUidGenerator.Generate();
            string instanceUid1 = TestUidGenerator.Generate();
            string instanceUid2 = TestUidGenerator.Generate();
            string instanceUid3 = TestUidGenerator.Generate();

            // One is on seriesUid1 and instanceUid1
            DicomDataset dataset1 = Samples.CreateRandomInstanceDataset(studyInstanceUid: studyUid, seriesInstanceUid: seriesUid1, sopInstanceUid: instanceUid1);

            dataset1.Add(identificationCodeElement);
            dataset1.AddOrUpdate(new DicomSignedShort(privateTag, 1));
            dataset1.Add(standardTagSeries, "ManufacturerModelName1");
            dataset1.Add(standardTagStudy, "0");

            // One is on seriesUid1 and instanceUid2
            DicomDataset dataset2 = Samples.CreateRandomInstanceDataset(studyInstanceUid: studyUid, seriesInstanceUid: seriesUid1, sopInstanceUid: instanceUid2);

            dataset2.Add(identificationCodeElement);
            dataset2.AddOrUpdate(new DicomSignedShort(privateTag, 2));
            dataset2.Add(standardTagSeries, "ManufacturerModelName2");
            dataset2.Add(standardTagStudy, "0");

            // One is on seriesUid2 and instanceUid3
            DicomDataset dataset3 = Samples.CreateRandomInstanceDataset(studyInstanceUid: studyUid, seriesInstanceUid: seriesUid2, sopInstanceUid: instanceUid3);

            dataset3.Add(identificationCodeElement);
            dataset3.AddOrUpdate(new DicomSignedShort(privateTag, 3));
            dataset3.Add(standardTagSeries, "ManufacturerModelName3");
            dataset3.Add(standardTagStudy, "1");
            try
            {
                // Add extended query tags

                await _client.AddExtendedQueryTagAsync(queryTags);

                try
                {
                    foreach (var queryTag in queryTags)
                    {
                        GetExtendedQueryTagEntry returnTag = await(await _client.GetExtendedQueryTagAsync(queryTag.Path)).GetValueAsync();
                        CompareExtendedQueryTagEntries(queryTag, returnTag);
                    }

                    // Upload test files
                    IEnumerable <DicomFile> dicomFiles = new DicomDataset[] { dataset1, dataset2, dataset3 }.Select(dataset => new DicomFile(dataset));

                    await _client.StoreAsync(dicomFiles, studyInstanceUid : string.Empty, cancellationToken : default);

                    // Query on instance for private tag
                    DicomWebAsyncEnumerableResponse <DicomDataset> queryInstanceResponse = await _client.QueryAsync(new Uri($"/instances?{privateTag.GetPath()}=3", UriKind.Relative), cancellationToken : default);

                    DicomDataset[] instanceResult = await queryInstanceResponse.ToArrayAsync();

                    Assert.Single(instanceResult);
                    Assert.Equal(instanceUid3, instanceResult[0].GetSingleValue <string>(DicomTag.SOPInstanceUID));

                    // Query on series for standardTagSeries
                    DicomWebAsyncEnumerableResponse <DicomDataset> querySeriesResponse = await _client.QueryAsync(new Uri($"/series?{standardTagSeries.GetPath()}=ManufacturerModelName2", UriKind.Relative), cancellationToken : default);

                    DicomDataset[] seriesResult = await querySeriesResponse.ToArrayAsync();

                    Assert.Single(seriesResult);
                    Assert.Equal(seriesUid1, seriesResult[0].GetSingleValue <string>(DicomTag.SeriesInstanceUID));

                    // Query on study for standardTagStudy
                    DicomWebAsyncEnumerableResponse <DicomDataset> queryStudyResponse = await _client.QueryAsync(new Uri($"/studies?{standardTagStudy.GetPath()}=1", UriKind.Relative), cancellationToken : default);

                    DicomDataset[] studyResult = await queryStudyResponse.ToArrayAsync();

                    Assert.Single(studyResult);
                    Assert.Equal(studyUid, seriesResult[0].GetSingleValue <string>(DicomTag.StudyInstanceUID));
                }
                finally
                {
                    await _client.DeleteStudyAsync(studyUid);
                }
            }
            finally
            {
                // Cleanup extended query tags, also verify GetExtendedQueryTagsAsync.
                var responseQueryTags = await(await _client.GetExtendedQueryTagsAsync()).GetValueAsync();
                foreach (var rTag in responseQueryTags)
                {
                    if (queryTags.Any(tag => tag.Path == rTag.Path))
                    {
                        await _client.DeleteExtendedQueryTagAsync(rTag.Path);
                    }
                }
            }
        }
Exemple #3
0
        private void CompareExtendedQueryTagEntries(AddExtendedQueryTagEntry addedTag, GetExtendedQueryTagEntry returnedTag)
        {
            if (addedTag == null || returnedTag == null)
            {
                Assert.True(addedTag == null && returnedTag == null);
                return;
            }

            Assert.True(string.Equals(returnedTag.Path, addedTag.Path, StringComparison.OrdinalIgnoreCase) &&
                        string.Equals(addedTag.VR, returnedTag.VR, StringComparison.OrdinalIgnoreCase) &&
                        addedTag.Level.Equals(returnedTag.Level));
        }
        public async Task GivenExtendedQueryTagWithErrors_WhenReindexing_ThenShouldSucceedWithErrors()
        {
            // Define tags
            DicomTag tag      = DicomTag.PatientAge;
            string   tagValue = "053Y";

            // Try to delete this extended query tag if it exists.
            await CleanupExtendedQueryTag(tag);

            // Define DICOM files
            DicomDataset instance1 = Samples.CreateRandomInstanceDataset();
            DicomDataset instance2 = Samples.CreateRandomInstanceDataset();
            DicomDataset instance3 = Samples.CreateRandomInstanceDataset();

            // Annotate files
            // (Disable Auto-validate)
            instance1.NotValidated();
            instance2.NotValidated();

            instance1.Add(tag, "foobar");
            instance2.Add(tag, "invalid");
            instance3.Add(tag, tagValue);

            // Upload files (with a few errors)
            await _instanceManager.StoreAsync(new DicomFile(instance1));

            await _instanceManager.StoreAsync(new DicomFile(instance2));

            await _instanceManager.StoreAsync(new DicomFile(instance3));

            // Add extended query tags
            var operationStatus = await _tagManager.AddTagsAsync(
                new AddExtendedQueryTagEntry[]
            {
                new AddExtendedQueryTagEntry {
                    Path = tag.GetPath(), VR = tag.GetDefaultVR().Code, Level = QueryTagLevel.Instance
                },
            });

            Assert.Equal(OperationRuntimeStatus.Completed, operationStatus.Status);

            // Check specific tag
            GetExtendedQueryTagEntry actual = await _tagManager.GetTagAsync(tag.GetPath());

            Assert.Equal(tag.GetPath(), actual.Path);
            Assert.Equal(2, actual.Errors.Count);
            // It should be disabled by default
            Assert.Equal(QueryStatus.Disabled, actual.QueryStatus);

            // Verify Errors
            var errors = await _tagManager.GetTagErrorsAsync(tag.GetPath(), 2, 0);

            Assert.Equal(2, errors.Count);

            Assert.Equal(errors[0].ErrorMessage, (await _tagManager.GetTagErrorsAsync(tag.GetPath(), 1, 0)).Single().ErrorMessage);
            Assert.Equal(errors[1].ErrorMessage, (await _tagManager.GetTagErrorsAsync(tag.GetPath(), 1, 1)).Single().ErrorMessage);

            var exception = await Assert.ThrowsAsync <DicomWebException>(() => _client.QueryInstancesAsync($"{tag.GetPath()}={tagValue}"));

            Assert.Equal(HttpStatusCode.BadRequest, exception.StatusCode);

            // Enable QIDO on Tag
            actual = await _tagManager.UpdateExtendedQueryTagAsync(tag.GetPath(), new UpdateExtendedQueryTagEntry()
            {
                QueryStatus = QueryStatus.Enabled
            });

            Assert.Equal(QueryStatus.Enabled, actual.QueryStatus);

            var response = await _client.QueryInstancesAsync($"{tag.GetPath()}={tagValue}");

            Assert.True(response.ResponseHeaders.Contains(ErroneousDicomAttributesHeader));
            var values = response.ResponseHeaders.GetValues(ErroneousDicomAttributesHeader);

            Assert.Single(values);
            Assert.Equal(tag.GetPath(), values.First());
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            // Verify result
            DicomDataset[] instances = await response.ToArrayAsync();

            Assert.Contains(instances, instance => instance.ToInstanceIdentifier().Equals(instance3.ToInstanceIdentifier()));
        }
 public GetExtendedQueryTagResponse(GetExtendedQueryTagEntry extendedQueryTagEntry)
 {
     ExtendedQueryTag = extendedQueryTagEntry;
 }
Exemple #6
0
 public UpdateExtendedQueryTagResponse(GetExtendedQueryTagEntry tagEntry)
 {
     TagEntry = EnsureArg.IsNotNull(tagEntry, nameof(tagEntry));
 }