public async Task GivenExistingExtendedQueryTagandTagError_WhenDeleteExtendedQueryTag_ThenTagErrorShouldAlsoBeRemoved() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomTag tag = DicomTag.DeviceSerialNumber; long watermark = await AddInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid); int tagKey = await AddTagAsync(tag); ValidationErrorCode errorCode = ValidationErrorCode.InvalidCharacters; await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey, errorCode, watermark); var extendedQueryTagErrorBeforeTagDeletion = await _extendedQueryTagErrorStore.GetExtendedQueryTagErrorsAsync(tag.GetPath(), int.MaxValue, 0); Assert.Equal(1, extendedQueryTagErrorBeforeTagDeletion.Count); var extendedQueryTagBeforeTagDeletion = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); await _extendedQueryTagStore.DeleteExtendedQueryTagAsync(tag.GetPath(), tag.GetDefaultVR().Code); await Assert.ThrowsAsync <ExtendedQueryTagNotFoundException>( () => _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath())); await Assert.ThrowsAsync <ExtendedQueryTagNotFoundException>( () => _extendedQueryTagErrorStore.GetExtendedQueryTagErrorsAsync(tag.GetPath(), 1, 0)); Assert.False(await _errorStoreTestHelper.DoesExtendedQueryTagErrorExistAsync(tagKey)); }
private static void ValidateVRCode(DicomTag tag, string vrCode, string tagPath) { DicomVR dicomVR = string.IsNullOrWhiteSpace(vrCode) ? null : ParseVRCode(vrCode, tagPath); if (tag.DictionaryEntry != DicomDictionary.UnknownTag) { // if VR is specified for knownTag, validate if (dicomVR != null) { if (!tag.DictionaryEntry.ValueRepresentations.Contains(dicomVR)) { // not a valid VR throw new ExtendedQueryTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.UnsupportedVRCodeOnTag, vrCode, tagPath, tag.GetDefaultVR())); } } else { // otherwise, get default one dicomVR = tag.GetDefaultVR(); } } else { // for unknown tag, vrCode is required if (dicomVR == null) { throw new ExtendedQueryTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.MissingVRCode, tagPath)); } } EnsureVRIsSupported(dicomVR, tagPath); }
public async Task GivenTags_WhenDeleteTag_ThenAssociatedErrorsShouldBeRemoved() { string studyUid = TestUidGenerator.Generate(); string seriesUid = TestUidGenerator.Generate(); string instanceUid = TestUidGenerator.Generate(); // add instances long watermark = await AddInstanceAsync(studyUid, seriesUid, instanceUid); // add tag DicomTag tag1 = DicomTag.DeviceSerialNumber; int tagKey1 = await AddTagAsync(tag1); DicomTag tag2 = DicomTag.DeviceID; int tagKey2 = await AddTagAsync(tag2); // add errors ValidationErrorCode errorCode = ValidationErrorCode.DateIsInvalid; // add error on instance for both tag await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey1, errorCode, watermark); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey2, errorCode, watermark); // delete tag await _extendedQueryTagStore.DeleteExtendedQueryTagAsync(tag1.GetPath(), tag1.GetDefaultVR().Code); // check errors Assert.False(await _errorStoreTestHelper.DoesExtendedQueryTagErrorExistAsync(tagKey1)); Assert.True(await _errorStoreTestHelper.DoesExtendedQueryTagErrorExistAsync(tagKey2)); }
/// <summary> /// Normalize custom tag entry before saving to CustomTagStore. /// </summary> /// <param name="customTagEntry">The custom tag entry.</param> /// <returns>Normalize custom tag entry.</returns> public static CustomTagEntry Normalize(this CustomTagEntry customTagEntry) { DicomTagParser dicomTagParser = new DicomTagParser(); DicomTag[] tags; if (!dicomTagParser.TryParse(customTagEntry.Path, out tags, supportMultiple: false)) { // not a valid dicom tag path throw new CustomTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.InvalidCustomTag, customTagEntry)); } DicomTag tag = tags[0]; string path = tag.GetPath(); string vr = customTagEntry.VR; // when VR is not specified for standard tag, if (!tag.IsPrivate && tag.DictionaryEntry != DicomDictionary.UnknownTag) { if (string.IsNullOrWhiteSpace(vr)) { vr = tag.GetDefaultVR()?.Code; } } vr = vr.ToUpperInvariant(); return(new CustomTagEntry(path, vr, customTagEntry.Level, customTagEntry.Status)); }
public void GivenVROfLowerCase_WhenFormalizing_ThenVRShouldBeUpperCase() { DicomTag tag = DicomTag.DeviceLabel; CustomTagEntry entry = new CustomTagEntry(tag.GetPath(), tag.GetDefaultVR().Code.ToLowerInvariant(), CustomTagLevel.Instance, CustomTagStatus.Added); CustomTagEntry normalized = entry.Normalize(); Assert.Equal(entry.VR.ToUpperInvariant(), normalized.VR); }
public void GivenStandardTagWithoutVR_WhenNormalizing_ThenVRShouldBeFilled(string vr) { DicomTag tag = DicomTag.DeviceSerialNumber; AddExtendedQueryTagEntry entry = CreateExtendedQueryTagEntry(tag.GetPath(), vr, null, QueryTagLevel.Instance); AddExtendedQueryTagEntry normalized = entry.Normalize(); Assert.Equal(tag.GetDefaultVR().Code, normalized.VR); }
public void GivenStandardTagWithoutVR_WhenFormalizing_ThenVRShouldBeFilled(string vr) { DicomTag tag = DicomTag.DeviceSerialNumber; CustomTagEntry entry = new CustomTagEntry(tag.GetPath(), vr, CustomTagLevel.Instance, CustomTagStatus.Added); CustomTagEntry normalized = entry.Normalize(); Assert.Equal(tag.GetDefaultVR().Code, normalized.VR); }
/// <summary> /// Initializes a new instance of the <see cref="QueryTag"/> class. /// </summary> /// <remarks>Used for constuctoring from core dicom tag.PatientName e.g. </remarks> /// <param name="tag">The core dicom Tag.</param> public QueryTag(DicomTag tag) { EnsureArg.IsNotNull(tag, nameof(tag)); Tag = tag; VR = tag.GetDefaultVR(); Level = QueryLimit.GetQueryTagLevel(tag); ExtendedQueryTagStoreEntry = null; }
/// <summary> /// Validate custom tag entry. /// </summary> /// <param name="tagEntry">the tag entry.</param> private void ValidateCustomTagEntry(CustomTagEntry tagEntry) { DicomTag tag = ParseTag(tagEntry.Path); // cannot be any tag we already support if (QueryLimit.AllInstancesTags.Contains(tag)) { throw new CustomTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.CustomTagAlreadyExists, tag.DictionaryEntry.Name)); } if (tag.IsPrivate) { // this is private tag, VR is required ParseVRCode(tagEntry.VR); EnsureVRIsSupported(tagEntry.VR); } else { // stardard tag must have name - should not be "Unknown". if (tag.DictionaryEntry.Equals(DicomDictionary.UnknownTag)) { // not a valid dicom tag throw new CustomTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.InvalidCustomTag, tag)); } if (string.IsNullOrWhiteSpace(tagEntry.VR)) { // When VR is missing for standard tag, still need to verify VRCode string vrCode = tag.GetDefaultVR()?.Code; EnsureVRIsSupported(vrCode); } else { // when VR is specified, verify it's correct // parse VR DicomVR vr = ParseVRCode(tagEntry.VR); EnsureVRIsSupported(vr.Code); if (!tag.DictionaryEntry.ValueRepresentations.Contains(vr)) { // not a valid VR throw new CustomTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.UnsupportedVRCodeOnTag, vr.Code, tag)); } } } }
public void GivenDisabledTag_WhenParse_ThenShouldThrowException() { DicomTag tag1 = DicomTag.PatientAge; QueryTag[] tags = new QueryTag[] { new QueryTag(new ExtendedQueryTagStoreEntry(1, tag1.GetPath(), tag1.GetDefaultVR().Code, null, QueryTagLevel.Instance, ExtendedQueryTagStatus.Ready, QueryStatus.Disabled, 1)), // disabled }; var parameters = CreateParameters( new Dictionary <string, string> { { tag1.GetFriendlyName(), "CoronaPatient" }, }, QueryResource.AllInstances); var exp = Assert.Throws <QueryParseException>(() => _queryParser.Parse(parameters, tags)); Assert.Equal($"Query is disabled on specified attribute '{tag1.GetFriendlyName()}'.", exp.Message); }
public void GivenErroneousTag_WhenParse_ThenShouldBeInList() { DicomTag tag1 = DicomTag.PatientAge; DicomTag tag2 = DicomTag.PatientAddress; QueryTag[] tags = new QueryTag[] { new QueryTag(new ExtendedQueryTagStoreEntry(1, tag1.GetPath(), tag1.GetDefaultVR().Code, null, QueryTagLevel.Instance, ExtendedQueryTagStatus.Ready, QueryStatus.Enabled, 1)), // has error new QueryTag(new ExtendedQueryTagStoreEntry(2, tag2.GetPath(), tag2.GetDefaultVR().Code, null, QueryTagLevel.Instance, ExtendedQueryTagStatus.Ready, QueryStatus.Enabled, 0)), // no error }; QueryExpression queryExpression = _queryParser.Parse( CreateParameters( new Dictionary <string, string> { { tag1.GetFriendlyName(), "CoronaPatient" }, { tag2.GetPath(), "20200403" }, }, QueryResource.AllInstances), tags); Assert.Single(queryExpression.ErroneousTags); Assert.Equal(queryExpression.ErroneousTags.First(), tag1.GetFriendlyName()); }
/// <summary> /// Normalize extended query tag entry before saving to ExtendedQueryTagStore. /// </summary> /// <param name="extendedQueryTagEntry">The extended query tag entry.</param> /// <returns>Normalize extended query tag entry.</returns> public static AddExtendedQueryTagEntry Normalize(this AddExtendedQueryTagEntry extendedQueryTagEntry) { DicomTagParser dicomTagParser = new DicomTagParser(); DicomTag[] tags; if (!dicomTagParser.TryParse(extendedQueryTagEntry.Path, out tags, supportMultiple: false)) { // not a valid dicom tag path throw new ExtendedQueryTagEntryValidationException( string.Format(CultureInfo.InvariantCulture, DicomCoreResource.InvalidExtendedQueryTag, extendedQueryTagEntry)); } DicomTag tag = tags[0]; string path = tag.GetPath(); string vr = extendedQueryTagEntry.VR; string privateCreator = string.IsNullOrWhiteSpace(extendedQueryTagEntry.PrivateCreator) ? null : extendedQueryTagEntry.PrivateCreator; // when VR is not specified for known tags if (tag.DictionaryEntry != DicomDictionary.UnknownTag) { if (string.IsNullOrWhiteSpace(vr)) { vr = tag.GetDefaultVR()?.Code; } } vr = vr?.ToUpperInvariant(); return(new AddExtendedQueryTagEntry() { Path = path, VR = vr, PrivateCreator = privateCreator, Level = extendedQueryTagEntry.Level, }); }
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 static ExtendedQueryTagStoreEntry BuildExtendedQueryTagStoreEntry(this DicomTag tag, int key = 1, string vr = null, string privateCreator = null, QueryTagLevel level = QueryTagLevel.Series, ExtendedQueryTagStatus status = ExtendedQueryTagStatus.Ready) { return(new ExtendedQueryTagStoreEntry(key: key, path: tag.GetPath(), vr: vr ?? tag.GetDefaultVR().Code, privateCreator: privateCreator, level: level, status: status)); }
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())); }
public static AddExtendedQueryTagEntry BuildAddExtendedQueryTagEntry(this DicomTag tag, string vr = null, string privateCreator = null, QueryTagLevel level = QueryTagLevel.Series) { return(new AddExtendedQueryTagEntry { Path = tag.GetPath(), VR = vr ?? tag.GetDefaultVR()?.Code, PrivateCreator = privateCreator, Level = level.ToString() }); }
public static GetExtendedQueryTagEntry BuildGetExtendedQueryTagEntry(this DicomTag tag, string vr = null, string privateCreator = null, QueryTagLevel level = QueryTagLevel.Series, ExtendedQueryTagStatus status = ExtendedQueryTagStatus.Ready) { return(new GetExtendedQueryTagEntry { Path = tag.GetPath(), VR = vr ?? tag.GetDefaultVR()?.Code, PrivateCreator = privateCreator, Level = level, Status = status }); }
public void GivenStandardTagAsKeyword_WhenNormalizing_ThenVRShouldBeFilled() { DicomTag tag = DicomTag.DeviceSerialNumber; AddExtendedQueryTagEntry entry = CreateExtendedQueryTagEntry(path: tag.DictionaryEntry.Keyword, tag.GetDefaultVR().Code, null, QueryTagLevel.Instance); string expectedPath = tag.GetPath(); AddExtendedQueryTagEntry normalized = entry.Normalize(); Assert.Equal(normalized.Path, expectedPath); }
public void GivenVROfLowerCase_WhenNormalizing_ThenVRShouldBeUpperCase() { DicomTag tag = DicomTag.DeviceLabel; AddExtendedQueryTagEntry entry = CreateExtendedQueryTagEntry(tag.GetPath(), tag.GetDefaultVR().Code.ToLowerInvariant(), null, QueryTagLevel.Instance); AddExtendedQueryTagEntry normalized = entry.Normalize(); Assert.Equal(entry.VR.ToUpperInvariant(), normalized.VR); }
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>()); }
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 void GivenStandardTagAsKeyword_WhenFormalizing_ThenVRShouldBeFilled() { DicomTag tag = DicomTag.DeviceSerialNumber; CustomTagEntry entry = new CustomTagEntry(path: tag.DictionaryEntry.Keyword, tag.GetDefaultVR().Code, CustomTagLevel.Instance, CustomTagStatus.Added); string expectedPath = tag.GetPath(); CustomTagEntry normalized = entry.Normalize(); Assert.Equal(normalized.Path, expectedPath); }
public static CustomTagEntry BuildCustomTagEntry(this DicomTag tag, CustomTagLevel level = CustomTagLevel.Series, CustomTagStatus status = CustomTagStatus.Added) { return(new CustomTagEntry(path: tag.GetPath(), vr: tag.GetDefaultVR()?.Code, level: level, status: status)); }
public void GivenDicomTag_WhenGetDefaultVR_ThenShouldReturnExpectedValue(DicomTag dicomTag, DicomVR expectedVR) { Assert.Equal(expectedVR, dicomTag.GetDefaultVR()); }