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)); }
public void GivenPrivateIdentificationCodeWithoutVR_WhenValidating_ThenShouldSucceed() { DicomTag dicomTag = new DicomTag(0x2201, 0x0010); AddExtendedQueryTagEntry entry = CreateExtendedQueryTagEntry(dicomTag.GetPath(), null); _extendedQueryTagEntryValidator.ValidateExtendedQueryTags(new AddExtendedQueryTagEntry[] { entry }); }
public async Task GivenExtendedQueryTagErrorsOnMultipleTags_WhenDeleteAssociatedInstance_ThenErrorCountShouldDecrease() { string studyInstanceUid = TestUidGenerator.Generate(); string seriesInstanceUid = TestUidGenerator.Generate(); string sopInstanceUid = TestUidGenerator.Generate(); DicomTag tag1 = DicomTag.DeviceSerialNumber; DicomTag tag2 = DicomTag.DeviceID; long watermark = await AddInstanceAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid); int tagKey1 = await AddTagAsync(tag1); int tagKey2 = await AddTagAsync(tag2); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey1, ValidationErrorCode.UidIsInvalid, watermark); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync(tagKey2, ValidationErrorCode.UidIsInvalid, watermark); // Delete instance await _indexDataStore.DeleteInstanceIndexAsync(new InstanceIdentifier(studyInstanceUid, seriesInstanceUid, sopInstanceUid, DefaultPartition.Key)); var tagEntry1 = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag1.GetPath()); Assert.Equal(0, tagEntry1.ErrorCount); var tagEntry2 = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag2.GetPath()); Assert.Equal(0, tagEntry2.ErrorCount); }
public async Task GivenExistingExtendedQueryTagError_WhenAddExtendedQueryTagError_ThenErrorCountShouldNotIncrease() { 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); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync( tagKey, ValidationErrorCode.UidIsInvalid, watermark); // add on same instance again await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync( tagKey, ValidationErrorCode.DateIsInvalid, watermark); var tagEntry = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); Assert.Equal(1, tagEntry.ErrorCount); }
public void GivenPrivateIdentificationCodeWithWrongVR_WhenValidating_ThenShouldSucceed() { DicomTag dicomTag = new DicomTag(0x2201, 0x0010); AddExtendedQueryTagEntry entry = CreateExtendedQueryTagEntry(dicomTag.GetPath(), DicomVR.AE.Code); Assert.Throws <ExtendedQueryTagEntryValidationException>(() => _extendedQueryTagEntryValidator.ValidateExtendedQueryTags(new AddExtendedQueryTagEntry[] { entry })); }
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)); }
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>()); }
/// <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 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); }
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 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 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 void GivenStandardTagWithVR_WhenFormalizing_ThenVRShouldNotBeUpdated() { DicomTag tag = DicomTag.DeviceSerialNumber; string vr = DicomVR.CS.Code; CustomTagEntry entry = new CustomTagEntry(tag.GetPath(), vr, CustomTagLevel.Instance, CustomTagStatus.Added); CustomTagEntry normalized = entry.Normalize(); Assert.Equal(vr, normalized.VR); }
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 GivenStandardTagWithVR_WhenNormalizing_ThenVRShouldNotBeUpdated() { DicomTag tag = DicomTag.DeviceSerialNumber; string vr = DicomVR.CS.Code; AddExtendedQueryTagEntry entry = CreateExtendedQueryTagEntry(tag.GetPath(), vr, null, QueryTagLevel.Instance); AddExtendedQueryTagEntry normalized = entry.Normalize(); Assert.Equal(vr, normalized.VR); }
public void GivenPrivateTagWithNonEmptyPrivateCreator_WhenNormalizing_ThenPrivateCreatorShouldBeNull(string privateCreator) { DicomTag tag1 = new DicomTag(0x0405, 0x1001); AddExtendedQueryTagEntry normalized = new AddExtendedQueryTagEntry() { Level = QueryTagLevel.Instance.ToString(), Path = tag1.GetPath(), PrivateCreator = privateCreator, VR = DicomVRCode.CS }.Normalize(); Assert.Null(normalized.PrivateCreator); }
public async Task GivenValidTag_WhenGetTag_ThenShouldSucceed() { DicomTag tag = DicomTag.DeviceSerialNumber; var expected = tag.BuildAddExtendedQueryTagEntry(); IReadOnlyList <int> keys = await AddExtendedQueryTagsAsync(new AddExtendedQueryTagEntry[] { expected }, ready : true); var actual = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); AssertTag(keys.Single(), expected, actual, ExtendedQueryTagStatus.Ready, operationId: null); }
private async Task CleanupExtendedQueryTag(DicomTag tag) { // Try to delete this extended query tag. try { await _tagManager.DeleteExtendedQueryTagAsync(tag.GetPath()); } catch (DicomWebException) { } }
public async Task GivenValidTagPath_WhenDeleteExtendedQueryTagIsInvoked_ThenShouldSucceed() { DicomTag tag = DicomTag.DeviceSerialNumber; string tagPath = tag.GetPath(); var entry = new ExtendedQueryTagStoreJoinEntry(tag.BuildExtendedQueryTagStoreEntry()); _extendedQueryTagStore.GetExtendedQueryTagAsync(tagPath, default).Returns(entry); await _extendedQueryTagService.DeleteExtendedQueryTagAsync(tagPath); await _extendedQueryTagStore.Received(1).DeleteExtendedQueryTagAsync(tagPath, entry.VR); }
public void GivenExtendedQueryPrivateTag_WithUrl_ParseSucceeds() { DicomTag tag = new DicomTag(0x0405, 0x1001, "PrivateCreator1"); string value = "Test"; var queryString = $"{tag.GetPath()}={value}"; QueryTag queryTag = new QueryTag(tag.BuildExtendedQueryTagStoreEntry(vr: DicomVRCode.CS, level: QueryTagLevel.Study)); QueryExpression queryExpression = _queryParser.Parse(CreateRequest(GetQueryCollection(queryString), QueryResource.AllStudies), new[] { queryTag }); Assert.Equal(queryTag, queryExpression.FilterConditions.First().QueryTag); }
public async Task GivenValidExtendedQueryTag_WhenAddExtendedQueryTag_ThenTagQueryStatusShouldBeEnabled() { DicomTag tag = DicomTag.DeviceSerialNumber; AddExtendedQueryTagEntry extendedQueryTagEntry = tag.BuildAddExtendedQueryTagEntry(); await AddExtendedQueryTagsAsync(new AddExtendedQueryTagEntry[] { extendedQueryTagEntry }); var tagEntry = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); Assert.Equal(QueryStatus.Enabled, tagEntry.QueryStatus); }
public async Task GivenValidTag_WhenUpdateTagQueryStatus_ThenShouldSucceed() { DicomTag tag = DicomTag.DeviceSerialNumber; var addEntry = tag.BuildAddExtendedQueryTagEntry(); IReadOnlyList <int> keys = await AddExtendedQueryTagsAsync(new AddExtendedQueryTagEntry[] { addEntry }, ready : false); var updateEntry = await _extendedQueryTagStore.UpdateQueryStatusAsync(tag.GetPath(), QueryStatus.Disabled); AssertTag(keys.Single(), addEntry, updateEntry, ExtendedQueryTagStatus.Adding, queryStatus: QueryStatus.Disabled); updateEntry = await _extendedQueryTagStore.UpdateQueryStatusAsync(tag.GetPath(), QueryStatus.Enabled); AssertTag(keys.Single(), addEntry, updateEntry, ExtendedQueryTagStatus.Adding, queryStatus: QueryStatus.Enabled); Guid id = Guid.NewGuid(); await _extendedQueryTagStore.AssignReindexingOperationAsync(keys, id); updateEntry = await _extendedQueryTagStore.UpdateQueryStatusAsync(tag.GetPath(), QueryStatus.Enabled); AssertTag(keys.Single(), addEntry, updateEntry, ExtendedQueryTagStatus.Adding, queryStatus: QueryStatus.Enabled, operationId: id); }
public async Task GivenValidTagWithOperation_WhenGetTag_ThenShouldSucceedAndIncludeId() { Guid id = Guid.NewGuid(); DicomTag tag = DicomTag.AcquisitionDateTime; var expected = tag.BuildAddExtendedQueryTagEntry(); IReadOnlyList <int> keys = await AddExtendedQueryTagsAsync(new AddExtendedQueryTagEntry[] { expected }, ready : false); await _extendedQueryTagStore.AssignReindexingOperationAsync(keys, id); var actual = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); AssertTag(keys.Single(), expected, actual, ExtendedQueryTagStatus.Adding, operationId: id); }
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()); }
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 async Task GivenExtendedQueryTagError_WhenAddExtendedQueryTagError_ThenTagQueryStatusShouldBeDisabled() { 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); await _extendedQueryTagErrorStore.AddExtendedQueryTagErrorAsync( tagKey, ValidationErrorCode.UidIsInvalid, watermark); var tagEntry = await _extendedQueryTagStore.GetExtendedQueryTagAsync(tag.GetPath()); Assert.Equal(QueryStatus.Disabled, tagEntry.QueryStatus); }
/// <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 static CustomTagStoreEntry BuildCustomTagStoreEntry(this DicomTag tag, long key = 1, CustomTagLevel level = CustomTagLevel.Series, CustomTagStatus status = CustomTagStatus.Reindexing) { return(new CustomTagStoreEntry(key: key, path: tag.GetPath(), vr: tag.DictionaryEntry.ValueRepresentations[0].Code, level: level, status: status)); }
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)); }