public async Task GivenSeriesTag_WhenReindexWithOldInstance_ThenTagValueShouldNotBeUpdated() { DicomTag tag = DicomTag.AcquisitionDeviceProcessingCode; string tagValue1 = "test1"; string tagValue2 = "test2"; string studyUid = TestUidGenerator.Generate(); string seriesUid = TestUidGenerator.Generate(); DicomDataset dataset1 = Samples.CreateRandomInstanceDataset(studyUid, seriesUid); dataset1.Add(tag, tagValue1); DicomDataset dataset2 = Samples.CreateRandomInstanceDataset(studyUid, seriesUid); dataset2.Add(tag, tagValue2); Instance instance1 = await CreateInstanceIndexAsync(dataset1); Instance instance2 = await CreateInstanceIndexAsync(dataset2); var tagStoreEntry = await AddExtendedQueryTagAsync(tag.BuildAddExtendedQueryTagEntry(level: QueryTagLevel.Series)); QueryTag queryTag = new QueryTag(tagStoreEntry); await _indexDataStore.ReindexInstanceAsync(dataset2, instance2.Watermark, new[] { queryTag }); await _indexDataStore.ReindexInstanceAsync(dataset1, instance1.Watermark, new[] { queryTag }); var row = (await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, tagStoreEntry.Key, instance1.StudyKey, instance1.SeriesKey, null)).First(); Assert.Equal(tagValue2, row.TagValue); }
public async Task GivenValidAndInvalidTagValues_WhenValidate_ThenReturnedValidTagsAndStoredFailure() { DicomTag tag1 = DicomTag.DeviceSerialNumber; DicomTag tag2 = DicomTag.DeviceID; DicomDataset ds = Samples.CreateRandomInstanceDataset(); DicomElement element1 = new DicomLongString(tag1, "testvalue1"); DicomElement element2 = new DicomLongString(tag2, "testvalue2"); ds.Add(element1); ds.Add(element2); QueryTag queryTag1 = new QueryTag(new ExtendedQueryTagStoreEntry(1, tag1.GetPath(), tag1.GetDefaultVR().Code, null, QueryTagLevel.Instance, ExtendedQueryTagStatus.Ready, QueryStatus.Enabled, 0)); QueryTag queryTag2 = new QueryTag(new ExtendedQueryTagStoreEntry(2, tag2.GetPath(), tag2.GetDefaultVR().Code, null, QueryTagLevel.Instance, ExtendedQueryTagStatus.Ready, QueryStatus.Enabled, 0)); // Throw exception when validate element1 var ex = ElementValidationExceptionFactory.CreateDateIsInvalidException("testname", "testvalue"); _minimumValidator.When(x => x.Validate(element1)) .Throw(ex); // only return querytag2 long watermark = 1; var validQueryTags = await _datasetValidator.ValidateAsync(ds, watermark, new[] { queryTag1, queryTag2 }); Assert.Single(validQueryTags); Assert.Same(queryTag2, validQueryTags.First()); // error for querytag1 is logged await _tagErrorsService.Received(1) .AddExtendedQueryTagErrorAsync(queryTag1.ExtendedQueryTagStoreEntry.Key, ex.ErrorCode, 1, Arg.Any <CancellationToken>()); }
private async Task ValidateAddNewExtendedQueryTagIndexData(QueryTagLevel level) { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomDataset dataset = Samples.CreateRandomInstanceDataset(studyInstanceUid, seriesInstanceUid, sopInstanceUid); DicomTag tag = DicomTag.ConversionType; string value = "SYN"; dataset.Add(tag, value); QueryTag queryTag = await AddExtendedQueryTag(tag.BuildAddExtendedQueryTagEntry(level: level)); try { long watermark = await CreateInstanceIndexAsync(dataset, new QueryTag[] { queryTag }); Instance instance = await _testHelper.GetInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, watermark); long?seriesKey = level != QueryTagLevel.Study ? instance.SeriesKey : null; long?instanceKey = level == QueryTagLevel.Instance ? instance.InstanceKey : null; var stringRows = await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, queryTag.ExtendedQueryTagStoreEntry.Key, instance.StudyKey, seriesKey, instanceKey); Assert.Single(stringRows); Assert.Equal(stringRows[0].TagValue, value); Assert.Equal(stringRows[0].Watermark, watermark); } finally { await _extendedQueryTagStore.DeleteExtendedQueryTagAsync(queryTag.ExtendedQueryTagStoreEntry.Path, queryTag.ExtendedQueryTagStoreEntry.VR); } }
public async Task GivenExistingExtendedQueryTagIndexData_WhenDeleteExtendedQueryTag_ThenShouldDeleteIndexData() { DicomTag tag = DicomTag.DeviceSerialNumber; // Prepare index data DicomDataset dataset = Samples.CreateRandomInstanceDataset(); dataset.Add(tag, "123"); await AddExtendedQueryTagsAsync(new AddExtendedQueryTagEntry[] { tag.BuildAddExtendedQueryTagEntry() }); ExtendedQueryTagStoreEntry storeEntry = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); QueryTag queryTag = new QueryTag(storeEntry); long watermark = await _indexDataStore.BeginCreateInstanceIndexAsync(1, dataset, new QueryTag[] { queryTag }); await _indexDataStore.EndCreateInstanceIndexAsync(1, dataset, watermark, new QueryTag[] { queryTag }); var extendedQueryTagIndexData = await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataForTagKeyAsync(ExtendedQueryTagDataType.StringData, storeEntry.Key); Assert.NotEmpty(extendedQueryTagIndexData); // Delete tag await _extendedQueryTagStore.DeleteExtendedQueryTagAsync(storeEntry.Path, storeEntry.VR); await VerifyTagNotExistAsync(storeEntry.Path); // Verify index data is removed extendedQueryTagIndexData = await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataForTagKeyAsync(ExtendedQueryTagDataType.StringData, storeEntry.Key); Assert.Empty(extendedQueryTagIndexData); }
internal async Task GivenDicomInstanceWithDifferentTypeOfExtendedQueryTags_WhenStore_ThenTheyShouldBeStoredInProperTable(ExtendedQueryTagDataType dataType, DicomElement element, object expectedValue) { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomDataset dataset = Samples.CreateRandomInstanceDataset(studyInstanceUid, seriesInstanceUid, sopInstanceUid); dataset.Add(element); QueryTagLevel level = QueryTagLevel.Study; var extendedQueryTagEntry = element.Tag.BuildAddExtendedQueryTagEntry(level: level); QueryTag queryTag = await AddExtendedQueryTag(extendedQueryTagEntry); try { long watermark = await CreateInstanceIndexAsync(dataset, new QueryTag[] { queryTag }); Instance instance = await _testHelper.GetInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, watermark); IReadOnlyList <ExtendedQueryTagDataRow> rows = await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(dataType, queryTag.ExtendedQueryTagStoreEntry.Key, instance.StudyKey); Assert.Single(rows); Assert.Equal(watermark, rows[0].Watermark); Assert.Equal(expectedValue, rows[0].TagValue); } finally { await _extendedQueryTagStore.DeleteExtendedQueryTagAsync(extendedQueryTagEntry.Path, extendedQueryTagEntry.VR); } }
public async Task GivenInstanceNotExist_WhenReindex_ThenShouldThrowException() { DicomTag tag = DicomTag.DeviceID; var tagStoreEntry = await AddExtendedQueryTagAsync(tag.BuildAddExtendedQueryTagEntry(level: QueryTagLevel.Instance)); DicomDataset dataset = Samples.CreateRandomInstanceDataset(); await Assert.ThrowsAsync <InstanceNotFoundException>(() => _indexDataStore.ReindexInstanceAsync(dataset, 0, new[] { new QueryTag(tagStoreEntry) })); }
public async Task GivenAValidDicomDatasetWithImplicitVR_WhenValidated_ThenItShouldThrowNotAcceptableException(DicomTransferSyntax transferSyntax) { var dicomDataset = Samples .CreateRandomInstanceDataset(dicomTransferSyntax: transferSyntax) .NotValidated(); await Assert.ThrowsAsync <NotAcceptableException>(() => _dicomDatasetValidator.ValidateAsync(dicomDataset, requiredStudyInstanceUid: null)); }
public void GivenDicomDatasetWithImplicitVR_WhenValidating_ThenItShouldThrowNotAcceptableException(DicomTransferSyntax transferSyntax) { var dicomDataset = Samples .CreateRandomInstanceDataset(dicomTransferSyntax: transferSyntax) .NotValidated(); Assert.Throws <NotAcceptableException>(() => ImplicitValueRepresentationValidator.Validate(dicomDataset)); }
public void GivenDicomDatasetWithNonImplicitVR_WhenValidating_ThenItShouldSucceed(DicomTransferSyntax transferSyntax) { var dicomDataset = Samples .CreateRandomInstanceDataset(dicomTransferSyntax: transferSyntax) .NotValidated(); ImplicitValueRepresentationValidator.Validate(dicomDataset); }
private async Task <long> AddInstanceAsync(string studyId, string seriesId, string sopInstanceId) { DicomDataset dataset = Samples.CreateRandomInstanceDataset(studyId, seriesId, sopInstanceId); long watermark = await _indexDataStore.BeginCreateInstanceIndexAsync(1, dataset); await _indexDataStore.EndCreateInstanceIndexAsync(1, dataset, watermark); return(watermark); }
public async Task GivenNoExtendedQueryTags_WhenCreateIndex_ThenShouldSucceed() { var extendedTags = await _extendedQueryTagStore.GetExtendedQueryTagsAsync(int.MaxValue); // make sure there is no extended query tags Assert.Empty(extendedTags); DicomDataset dataset = Samples.CreateRandomInstanceDataset(); await _indexDataStore.BeginCreateInstanceIndexAsync(DefaultPartition.Key, dataset, QueryTagService.CoreQueryTags); }
public async Task GivenPendingInstance_WhenReindex_ThenShouldThrowException() { DicomTag tag = DicomTag.DeviceDescription; var tagStoreEntry = await AddExtendedQueryTagAsync(tag.BuildAddExtendedQueryTagEntry(level: QueryTagLevel.Instance)); DicomDataset dataset = Samples.CreateRandomInstanceDataset(); long watermark = await _indexDataStore.BeginCreateInstanceIndexAsync(1, dataset); await Assert.ThrowsAsync <PendingInstanceException>(() => _indexDataStore.ReindexInstanceAsync(dataset, watermark, new[] { new QueryTag(tagStoreEntry) })); }
private async Task ValidateUpdateExistingExtendedQueryTagIndexData(QueryTagLevel level) { if (level == QueryTagLevel.Instance) { throw new System.ArgumentException("Update value on instance level is not valid case."); } string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomDataset dataset = Samples.CreateRandomInstanceDataset(studyInstanceUid, seriesInstanceUid, sopInstanceUid); DicomTag tag = DicomTag.ConversionType; string value = "SYN"; dataset.Add(tag, value); QueryTag queryTag = await AddExtendedQueryTag(tag.BuildAddExtendedQueryTagEntry(level: level)); try { // index extended query tags await CreateInstanceIndexAsync(dataset, new QueryTag[] { queryTag }); // update value = "NEWSYN"; dataset.AddOrUpdate(tag, value); sopInstanceUid = TestUidGenerator.Generate(); dataset.AddOrUpdate(DicomTag.SOPInstanceUID, sopInstanceUid); if (level == QueryTagLevel.Study) { seriesInstanceUid = TestUidGenerator.Generate(); dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, seriesInstanceUid); } // index new instance long watermark = await CreateInstanceIndexAsync(dataset, new QueryTag[] { queryTag }); Instance instance = await _testHelper.GetInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, watermark); long?seriesKey = level != QueryTagLevel.Study ? instance.SeriesKey : null; var stringRows = await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, queryTag.ExtendedQueryTagStoreEntry.Key, instance.StudyKey, seriesKey); Assert.Single(stringRows); Assert.Equal(stringRows[0].TagValue, value); Assert.Equal(stringRows[0].Watermark, watermark); } finally { await _extendedQueryTagStore.DeleteExtendedQueryTagAsync(queryTag.ExtendedQueryTagStoreEntry.Path, queryTag.ExtendedQueryTagStoreEntry.VR); } }
private async Task <Instance> StoreInstanceWithDifferentTagValues(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid, int index, IReadOnlyList <QueryTag> queryTags) { DicomDataset dataset = Samples.CreateRandomInstanceDataset(studyInstanceUid, seriesInstanceUid, sopInstanceUid); dataset.Add(new DicomDate(DicomTag.AcquisitionDate, DateTime.Parse("2020/2/2" + index))); dataset.Add(new DicomCodeString(DicomTag.ConversionType, "STRING" + index)); dataset.Add(new DicomFloatingPointDouble(DicomTag.DopplerCorrectionAngle, 1.0 + index)); dataset.Add(new DicomSignedLong(DicomTag.ReferencePixelX0, 1 + index)); dataset.Add(new DicomPersonName(DicomTag.DistributionNameRETIRED, "abc^abc" + index)); long watermark = await _indexDataStore.CreateInstanceIndexAsync(dataset, queryTags); return(await _testHelper.GetInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid, watermark)); }
public async Task GivenMaxTagKeyNotMatch_WhenCreateIndex_ThenShouldThrowException() { AddExtendedQueryTagEntry extendedQueryTagEntry = DicomTag.PatientAge.BuildAddExtendedQueryTagEntry(); var tagEntry = (await _extendedQueryTagStore.AddExtendedQueryTagsAsync(new[] { extendedQueryTagEntry }, maxAllowedCount: 128, ready: true))[0]; DicomDataset dataset = Samples.CreateRandomInstanceDataset(); // Add a new tag await _extendedQueryTagStore.AddExtendedQueryTagsAsync(new[] { DicomTag.PatientName.BuildAddExtendedQueryTagEntry() }, maxAllowedCount : 128, ready : true); var queryTags = new[] { new QueryTag(tagEntry) }; long watermark = await _indexDataStore.BeginCreateInstanceIndexAsync(DefaultPartition.Key, dataset, queryTags); await Assert.ThrowsAsync <ExtendedQueryTagsOutOfDateException>( () => _indexDataStore.EndCreateInstanceIndexAsync(DefaultPartition.Key, dataset, watermark, queryTags)); }
public async Task GivenStudyTag_WhenReindexWithNewInstance_ThenTagValueShouldBeUpdated() { DicomTag tag = DicomTag.DeviceSerialNumber; string tagValue1 = "test1"; string tagValue2 = "test2"; string tagValue3 = "test3"; string studyUid = TestUidGenerator.Generate(); DicomDataset dataset1 = Samples.CreateRandomInstanceDataset(studyUid); dataset1.Add(tag, tagValue1); DicomDataset dataset2 = Samples.CreateRandomInstanceDataset(studyUid); dataset2.Add(tag, tagValue2); DicomDataset dataset3 = Samples.CreateRandomInstanceDataset(studyUid); dataset3.Add(tag, tagValue3); Instance instance1 = await CreateInstanceIndexAsync(dataset1); Instance instance2 = await CreateInstanceIndexAsync(dataset2); Instance instance3 = await CreateInstanceIndexAsync(dataset3); var tagStoreEntry = await AddExtendedQueryTagAsync(tag.BuildAddExtendedQueryTagEntry(level: QueryTagLevel.Study)); QueryTag queryTag = new QueryTag(tagStoreEntry); // Simulate re-indexing, which may re-index an instance which may re-index // the instances for a particular study or series out-of-order await _indexDataStore.ReindexInstanceAsync(dataset2, instance2.Watermark, new[] { queryTag }); ExtendedQueryTagDataRow row = (await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, tagStoreEntry.Key, instance1.StudyKey, null, null)).Single(); Assert.Equal(tagValue2, row.TagValue); // Added await _indexDataStore.ReindexInstanceAsync(dataset3, instance3.Watermark, new[] { queryTag }); row = (await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, tagStoreEntry.Key, instance1.StudyKey, null, null)).Single(); Assert.Equal(tagValue3, row.TagValue); // Overwrite await _indexDataStore.ReindexInstanceAsync(dataset1, instance1.Watermark, new[] { queryTag }); row = (await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, tagStoreEntry.Key, instance1.StudyKey, null, null)).Single(); Assert.Equal(tagValue3, row.TagValue); // Do not overwrite }
public async Task GivenInstanceTag_WhenReindexWithIndexedInstance_ThenTagValueShouldNotBeUpdated() { DicomTag tag = DicomTag.DeviceLabel; string tagValue = "test"; var tagStoreEntry = await AddExtendedQueryTagAsync(tag.BuildAddExtendedQueryTagEntry(level: QueryTagLevel.Instance)); DicomDataset dataset = Samples.CreateRandomInstanceDataset(); dataset.Add(tag, tagValue); var instance = await CreateInstanceIndexAsync(dataset); await _indexDataStore.ReindexInstanceAsync(dataset, instance.Watermark, new[] { new QueryTag(tagStoreEntry) }); var row = (await _extendedQueryTagStoreTestHelper.GetExtendedQueryTagDataAsync(ExtendedQueryTagDataType.StringData, tagStoreEntry.Key, instance.StudyKey, instance.SeriesKey, instance.InstanceKey)).First(); Assert.Equal(tagValue, row.TagValue); }
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); } } } }
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 async Task GivenExtendedQueryTag_WhenReindexing_ThenShouldSucceed() { DicomTag weightTag = DicomTag.PatientWeight; DicomTag sizeTag = DicomTag.PatientSize; // Try to delete these extended query tags. await CleanupExtendedQueryTag(weightTag); await CleanupExtendedQueryTag(sizeTag); // Define DICOM files DicomDataset instance1 = Samples.CreateRandomInstanceDataset(); instance1.Add(weightTag, 68.0M); instance1.Add(sizeTag, 1.78M); DicomDataset instance2 = Samples.CreateRandomInstanceDataset(); instance2.Add(weightTag, 50.0M); instance2.Add(sizeTag, 1.5M); // Upload files Assert.True((await _instanceManager.StoreAsync(new DicomFile(instance1))).IsSuccessStatusCode); Assert.True((await _instanceManager.StoreAsync(new DicomFile(instance2))).IsSuccessStatusCode); // Add extended query tag OperationStatus operation = await _tagManager.AddTagsAsync( new AddExtendedQueryTagEntry[] { new AddExtendedQueryTagEntry { Path = weightTag.GetPath(), VR = weightTag.GetDefaultVR().Code, Level = QueryTagLevel.Study }, new AddExtendedQueryTagEntry { Path = sizeTag.GetPath(), VR = sizeTag.GetDefaultVR().Code, Level = QueryTagLevel.Study }, }); Assert.Equal(OperationRuntimeStatus.Completed, operation.Status); // Check specific tag DicomWebResponse <GetExtendedQueryTagEntry> getResponse; GetExtendedQueryTagEntry entry; getResponse = await _client.GetExtendedQueryTagAsync(weightTag.GetPath()); entry = await getResponse.GetValueAsync(); Assert.Null(entry.Errors); Assert.Equal(QueryStatus.Enabled, entry.QueryStatus); getResponse = await _client.GetExtendedQueryTagAsync(sizeTag.GetPath()); entry = await getResponse.GetValueAsync(); Assert.Null(entry.Errors); Assert.Equal(QueryStatus.Enabled, entry.QueryStatus); // Query multiple tags // Note: We don't necessarily need to check the tags are the above ones, as another test may have added ones beforehand var multipleTags = await _tagManager.GetTagsAsync(2, 0); Assert.Equal(2, multipleTags.Count); Assert.Equal(multipleTags[0].Path, (await _tagManager.GetTagsAsync(1, 0)).Single().Path); Assert.Equal(multipleTags[1].Path, (await _tagManager.GetTagsAsync(1, 1)).Single().Path); // QIDO DicomWebAsyncEnumerableResponse <DicomDataset> queryResponse = await _client.QueryInstancesAsync($"{weightTag.GetPath()}=50.0"); DicomDataset[] instances = await queryResponse.ToArrayAsync(); Assert.Contains(instances, instance => instance.ToInstanceIdentifier().Equals(instance2.ToInstanceIdentifier())); }