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); }
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); } } } }
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; }
public UpdateExtendedQueryTagResponse(GetExtendedQueryTagEntry tagEntry) { TagEntry = EnsureArg.IsNotNull(tagEntry, nameof(tagEntry)); }