예제 #1
0
        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);
        }
예제 #2
0
        /// <inheritdoc />
        public async Task StoreDicomInstanceEntryAsync(
            IDicomInstanceEntry dicomInstanceEntry,
            CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(dicomInstanceEntry, nameof(dicomInstanceEntry));
            var partitionKey = _contextAccessor.RequestContext.GetPartitionKey();

            DicomDataset dicomDataset = await dicomInstanceEntry.GetDicomDatasetAsync(cancellationToken);

            IReadOnlyCollection <QueryTag> queryTags = await _queryTagService.GetQueryTagsAsync(cancellationToken : cancellationToken);

            long watermark = await _indexDataStore.BeginCreateInstanceIndexAsync(partitionKey, dicomDataset, queryTags, cancellationToken);

            var versionedInstanceIdentifier = dicomDataset.ToVersionedInstanceIdentifier(watermark);

            try
            {
                // We have successfully created the index, store the files.
                await Task.WhenAll(
                    StoreFileAsync(versionedInstanceIdentifier, dicomInstanceEntry, cancellationToken),
                    StoreInstanceMetadataAsync(dicomDataset, watermark, cancellationToken));

                await _indexDataStore.EndCreateInstanceIndexAsync(partitionKey, dicomDataset, watermark, queryTags, cancellationToken : cancellationToken);
            }
            catch (Exception)
            {
                // Exception occurred while storing the file. Try delete the index.
                await TryCleanupInstanceIndexAsync(versionedInstanceIdentifier);

                throw;
            }
        }
예제 #3
0
        public StoreOrchestratorTests()
        {
            _dicomDataset = new DicomDataset()
            {
                { DicomTag.StudyInstanceUID, DefaultStudyInstanceUid },
                { DicomTag.SeriesInstanceUID, DefaultSeriesInstanceUid },
                { DicomTag.SOPInstanceUID, DefaultSopInstanceUid },
            };

            _dicomInstanceEntry.GetDicomDatasetAsync(DefaultCancellationToken).Returns(_dicomDataset);
            _dicomInstanceEntry.GetStreamAsync(DefaultCancellationToken).Returns(_stream);

            _indexDataStore
            .BeginCreateInstanceIndexAsync(Arg.Any <int>(), _dicomDataset, Arg.Any <IEnumerable <QueryTag> >(), DefaultCancellationToken)
            .Returns(DefaultVersion);

            _queryTagService
            .GetQueryTagsAsync(Arg.Any <CancellationToken>())
            .Returns(_queryTags);

            _contextAccessor.RequestContext.DataPartitionEntry = new PartitionEntry(1, "Microsoft.Default");

            _storeOrchestrator = new StoreOrchestrator(
                _contextAccessor,
                _fileStore,
                _metadataStore,
                _indexDataStore,
                _deleteService,
                _queryTagService);
        }
        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);
        }
예제 #5
0
        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 StoreDatasetsAndInstances(DicomDataset dataset, bool flagToStoreInstance)
        {
            long version = await _indexDataStore.BeginCreateInstanceIndexAsync(1, dataset);

            var versionedInstanceIdentifier = dataset.ToVersionedInstanceIdentifier(version);

            if (flagToStoreInstance)
            {
                var dicomFile = new DicomFile(dataset);

                Samples.AppendRandomPixelData(5, 5, 0, dicomFile);

                await using MemoryStream stream = _recyclableMemoryStreamManager.GetStream();

                dicomFile.Save(stream);
                stream.Position = 0;
                await _fileStore.StoreFileAsync(
                    versionedInstanceIdentifier,
                    stream);
            }

            await _indexDataStore.EndCreateInstanceIndexAsync(1, dataset, version);
        }
 public static Task <long> BeginCreateInstanceIndexAsync(this IIndexDataStore indexDataStore, int partitionKey, DicomDataset dicomDataset, CancellationToken cancellationToken = default)
 => indexDataStore.BeginCreateInstanceIndexAsync(partitionKey, dicomDataset, Array.Empty <QueryTag>(), cancellationToken);
예제 #8
0
        public async Task GivenANonExistingDicomInstance_WhenAdded_ThenItShouldBeAdded()
        {
            DicomDataset dataset                = CreateTestDicomDataset();
            string       studyInstanceUid       = dataset.GetString(DicomTag.StudyInstanceUID);
            string       seriesInstanceUid      = dataset.GetString(DicomTag.SeriesInstanceUID);
            string       sopInstanceUid         = dataset.GetString(DicomTag.SOPInstanceUID);
            string       patientId              = dataset.GetString(DicomTag.PatientID);
            string       patientName            = dataset.GetString(DicomTag.PatientName);
            string       referringPhysicianName = dataset.GetString(DicomTag.ReferringPhysicianName);
            string       studyDescription       = dataset.GetString(DicomTag.StudyDescription);
            string       accessionNumber        = dataset.GetString(DicomTag.AccessionNumber);
            string       modality               = dataset.GetString(DicomTag.Modality);

            long version = await _indexDataStore.BeginCreateInstanceIndexAsync(1, dataset);

            IReadOnlyList <StudyMetadata> studyMetadataEntries = await _testHelper.GetStudyMetadataAsync(studyInstanceUid);

            Assert.Collection(
                studyMetadataEntries,
                entry => ValidateStudyMetadata(
                    studyInstanceUid,
                    patientId,
                    patientName,
                    referringPhysicianName,
                    new DateTime(2020, 3, 1, 0, 0, 0, DateTimeKind.Utc),
                    studyDescription,
                    accessionNumber,
                    entry));

            IReadOnlyList <SeriesMetadata> seriesMetadataEntries = await _testHelper.GetSeriesMetadataAsync(seriesInstanceUid);

            Assert.Collection(
                seriesMetadataEntries,
                entry => ValidateSeriesMetadata(
                    seriesInstanceUid,
                    modality,
                    new DateTime(2020, 3, 2, 0, 0, 0, DateTimeKind.Utc),
                    entry));

            // Make sure the ID matches between the study and series metadata.
            Assert.Equal(studyMetadataEntries[0].StudyKey, seriesMetadataEntries[0].StudyKey);

            IReadOnlyList <Instance> instances = await _testHelper.GetInstancesAsync(studyInstanceUid, seriesInstanceUid, sopInstanceUid);

            Assert.NotNull(instances);
            Assert.Single(instances);

            Instance instance = instances[0];

            Assert.Equal(studyInstanceUid, instance.StudyInstanceUid);
            Assert.Equal(seriesInstanceUid, instance.SeriesInstanceUid);
            Assert.Equal(sopInstanceUid, instance.SopInstanceUid);
            Assert.Equal(version, instance.Watermark);
            Assert.Equal((byte)IndexStatus.Creating, instance.Status);
            Assert.InRange(instance.LastStatusUpdatedDate, _startDateTime.AddSeconds(-1), Clock.UtcNow.AddSeconds(1));
            Assert.InRange(instance.CreatedDate, _startDateTime.AddSeconds(-1), Clock.UtcNow.AddSeconds(1));
        }