void IDisposable.Dispose()
        {
            // xunit does not seem to call IAsyncDispose.DisposeAsync()
            // Also wait should be okay in a test context
            foreach (string studyUid in _studiesToClean)
            {
                _client.DeleteStudyAsync(studyUid).Wait();
            }

            _studiesToClean.Clear();
        }
        private async Task EnsureFileIsStoredAsync(DicomFile dicomFile)
        {
            var instanceId = dicomFile.Dataset.ToInstanceIdentifier();

            try
            {
                await _client.DeleteStudyAsync(instanceId.StudyInstanceUid);
            }
            catch (DicomWebException ex) when(ex.StatusCode == HttpStatusCode.NotFound)
            {
                // No-op.
            }

            await InternalStoreAsync(new[] { dicomFile });
        }
示例#3
0
        public async Task GivenExistingStudy_WhenDeletingStudy_TheServerShouldReturnNoContentAndAllLevelsShouldBeRemoved()
        {
            var studyInstanceUid  = TestUidGenerator.Generate();
            var seriesInstanceUid = TestUidGenerator.Generate();
            var sopInstanceUid    = TestUidGenerator.Generate();

            await CreateFile(studyInstanceUid, seriesInstanceUid, sopInstanceUid);

            using (DicomWebResponse response = await _client.DeleteStudyAsync(studyInstanceUid))
            {
                Assert.Equal(HttpStatusCode.NoContent, response?.StatusCode);
            }

            await VerifyAllRemoval(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
        }
示例#4
0
        public async Task DisposeAsync()
        {
            foreach (string studyUid in _studiesToClean)
            {
                await _client.DeleteStudyAsync(studyUid);
            }

            _studiesToClean.Clear();
        }
示例#5
0
        public async Task GivenDeleteRequestForStudy_WhenResourceExists_ThenAuditLogEntriesShouldBeCreated()
        {
            InstanceIdentifier dicomInstance = await CreateDicomFileAndGetInstanceIdentifierAsync();

            await ExecuteAndValidate(
                () => _client.DeleteStudyAsync(dicomInstance.StudyInstanceUid),
                AuditEventSubType.Delete,
                $"studies/{dicomInstance.StudyInstanceUid}",
                HttpStatusCode.NoContent);
        }
        public async Task GivenAMultipartRequestWithAnInvalidMultipartSection_WhenStoring_TheServerShouldReturnAccepted()
        {
            var multiContent = new MultipartContent("related");

            multiContent.Headers.ContentType.Parameters.Add(new System.Net.Http.Headers.NameValueHeaderValue("type", $"\"{DicomWebConstants.MediaTypeApplicationDicom.MediaType}\""));

            var byteContent = new ByteArrayContent(Array.Empty <byte>());

            byteContent.Headers.ContentType = DicomWebConstants.MediaTypeApplicationDicom;
            multiContent.Add(byteContent);

            string studyInstanceUID = TestUidGenerator.Generate();

            try
            {
                DicomFile validFile = Samples.CreateRandomDicomFile(studyInstanceUID);

                await using (MemoryStream stream = _recyclableMemoryStreamManager.GetStream())
                {
                    await validFile.SaveAsync(stream);

                    var validByteContent = new ByteArrayContent(stream.ToArray());
                    validByteContent.Headers.ContentType = DicomWebConstants.MediaTypeApplicationDicom;
                    multiContent.Add(validByteContent);
                }

                using DicomWebResponse <DicomDataset> response = await _instancesManager.StoreAsync(multiContent, instanceId : DicomInstanceId.FromDicomFile(validFile));

                Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);

                await ValidateReferencedSopSequenceAsync(
                    response,
                    ConvertToReferencedSopSequenceEntry(validFile.Dataset));
            }
            finally
            {
                await _client.DeleteStudyAsync(studyInstanceUID);
            }
        }
        public async Task GivenInputAndOutputTransferSyntax_WhenRetrieveFrame_ThenServerShouldReturnExpectedContent(string testDataFolder, string mediaType, string transferSyntax)
        {
            TranscoderTestData transcoderTestData = TranscoderTestDataHelper.GetTestData(testDataFolder);
            DicomFile          inputDicomFile     = await DicomFile.OpenAsync(transcoderTestData.InputDicomFile);

            int numberOfFrames = DicomPixelData.Create(inputDicomFile.Dataset).NumberOfFrames;

            string studyInstanceUid  = inputDicomFile.Dataset.GetString(DicomTag.StudyInstanceUID);
            string seriesInstanceUid = inputDicomFile.Dataset.GetString(DicomTag.SeriesInstanceUID);
            string sopInstanceUid    = inputDicomFile.Dataset.GetString(DicomTag.SOPInstanceUID);

            DicomWebResponse <IEnumerable <DicomDataset> > tryQuery = await _client.QueryAsync(
                $"/studies/{studyInstanceUid}/series/{seriesInstanceUid}/instances?SOPInstanceUID={sopInstanceUid}");

            if (tryQuery.StatusCode == HttpStatusCode.OK)
            {
                await _client.DeleteStudyAsync(studyInstanceUid);
            }

            await _client.StoreAsync(new[] { inputDicomFile });

            DicomWebResponse <IReadOnlyList <Stream> > response = await _client.RetrieveFramesAsync(
                studyInstanceUid : studyInstanceUid,
                seriesInstanceUid : seriesInstanceUid,
                sopInstanceUid : sopInstanceUid,
                mediaType : mediaType,
                dicomTransferSyntax : transferSyntax,
                frames : GenerateFrames(numberOfFrames),
                cancellationToken : _defaultCancellationToken);

            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

            string byteStreamHash = TranscoderTestDataHelper.GetHashFromStream(response.Value[0]);

            Assert.Equal(transcoderTestData.MetaData.OutputFramesHashCode, byteStreamHash);

            await _client.DeleteStudyAsync(studyInstanceUid);
        }
示例#8
0
        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);
                    }
                }
            }
        }