public async Task GivenRandomContent_WhenStoring_TheServerShouldReturnConflict()
        {
            await using MemoryStream stream = _recyclableMemoryStreamManager.GetStream();

            DicomWebException exception = await Assert.ThrowsAsync <DicomWebException>(() => _client.StoreAsync(new[] { stream }));

            Assert.Equal(HttpStatusCode.Conflict, exception.StatusCode);
        }
Example #2
0
        public async Task GivenRetrieveRequestForFrame_WhenResourceIsFound_ThenAuditLogEntriesShouldBeCreated()
        {
            DicomFile dicomFile     = Samples.CreateRandomDicomFileWithPixelData(frames: 1);
            var       dicomInstance = dicomFile.Dataset.ToInstanceIdentifier();
            await _client.StoreAsync(new[] { dicomFile }, dicomInstance.StudyInstanceUid);

            await ExecuteAndValidate(
                () => _client.RetrieveFramesAsync(dicomInstance.StudyInstanceUid, dicomInstance.SeriesInstanceUid, dicomInstance.SopInstanceUid, frames: new int[] { 1 }),
                AuditEventSubType.Retrieve,
                $"studies/{dicomInstance.StudyInstanceUid}/series/{dicomInstance.SeriesInstanceUid}/instances/{dicomInstance.SopInstanceUid}/frames/1",
                HttpStatusCode.OK);
        }
Example #3
0
        private async Task <DicomDataset> PostDicomFileAsync(ResourceType resourceType, string studyInstanceUid, string seriesInstanceUid = null, string sopInstanceUid = null, DicomDataset dataSet = null)
        {
            DicomFile dicomFile = null;

            switch (resourceType)
            {
            case ResourceType.Study:
                dicomFile = Samples.CreateRandomDicomFile(studyInstanceUid);
                break;

            case ResourceType.Series:
                dicomFile = Samples.CreateRandomDicomFile(studyInstanceUid, seriesInstanceUid);
                break;

            case ResourceType.Instance:
                dicomFile = Samples.CreateRandomDicomFile(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
                break;
            }

            if (dataSet != null)
            {
                dicomFile.Dataset.AddOrUpdate(dataSet);
            }

            using (DicomWebResponse <DicomDataset> response = await _client.StoreAsync(new[] { dicomFile }))
            {
                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            }

            return(dicomFile.Dataset);
        }
        private async Task InternalStoreAsync(IEnumerable <DicomFile> dicomFiles)
        {
            await _client.StoreAsync(dicomFiles);

            foreach (DicomFile dicomFile in dicomFiles)
            {
                _studiesToClean.Add(dicomFile.Dataset.GetString(DicomTag.StudyInstanceUID));
            }
        }
Example #5
0
        public async Task GivenPostDicomRequest_WithAReadOnlyToken_ReturnUnauthorized()
        {
            if (AuthenticationSettings.SecurityEnabled)
            {
                DicomFile dicomFile     = Samples.CreateRandomDicomFileWithPixelData(frames: 1);
                var       dicomInstance = dicomFile.Dataset.ToInstanceIdentifier();

                IDicomWebClient   client    = _fixture.GetDicomWebClient(TestApplications.GlobalAdminServicePrincipal, TestUsers.User1);
                DicomWebException exception = await Assert.ThrowsAsync <DicomWebException>(
                    () => client.StoreAsync(new[] { dicomFile }, dicomInstance.StudyInstanceUid));

                Assert.Equal(HttpStatusCode.Forbidden, exception.StatusCode);
            }
        }
        private async Task <DicomDataset> PostDicomFileAsync(DicomDataset metadataItems = null)
        {
            DicomFile dicomFile1 = CreateDicomFile();

            if (metadataItems != null)
            {
                dicomFile1.Dataset.AddOrUpdate(metadataItems);
            }

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

            _createdDicomStudies.Add(dicomFile1.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID));

            return(dicomFile1.Dataset);
        }
Example #7
0
        private static void StoreRetrievedData(DicomFile dicomFile)
        {
            DicomWebResponse <DicomDataset> response = s_client.StoreAsync(new List <DicomFile>()
            {
                dicomFile
            }).Result;

            int statusCode = (int)response.StatusCode;

            if (statusCode != 409 && statusCode < 200 && statusCode > 299)
            {
                throw new HttpRequestException("Store operation failed", null, response.StatusCode);
            }

            return;
        }
Example #8
0
        private static void StoreRetrievedData(DicomFile dicomFile)
        {
            DicomWebResponse <DicomDataset> response = client.StoreAsync(new List <DicomFile>()
            {
                dicomFile
            }).Result;

            int statusCode = (int)response.StatusCode;

            if (statusCode != 409 && statusCode < 200 && statusCode > 299)
            {
                throw new Exception();
            }

            return;
        }
        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);
        }
Example #10
0
        private static async Task Stow(Message message, CancellationToken token)
        {
            PatientInstance pI = JsonSerializer.Deserialize <PatientInstance>(Encoding.UTF8.GetString(message.Body));

            // 400, 400, 100 - 16MB
            // 100, 100, 100 - 1MB
            // 100, 100, 50 - 0.5MB
            DicomFile dicomFile = Samples.CreateRandomDicomFileWithPixelData(
                pI,
                rows: 100,
                columns: 100,
                frames: 50);

            DicomWebResponse <DicomDataset> response = await client.StoreAsync(new List <DicomFile>() { dicomFile }, cancellationToken : token);

            int statusCode = (int)response.StatusCode;

            if (statusCode != 409 && statusCode < 200 && statusCode > 299)
            {
                throw new HttpRequestException("Stow operation failed", null, response.StatusCode);
            }

            return;
        }
Example #11
0
        private async Task CreateFile(string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid)
        {
            DicomFile dicomFile1 = Samples.CreateRandomDicomFile(studyInstanceUid, seriesInstanceUid, sopInstanceUid);

            await _client.StoreAsync(new[] { dicomFile1 }, studyInstanceUid);
        }
Example #12
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);
                    }
                }
            }
        }
        public async Task GivenInstanceWithFrames_WhenRetrieveRequestForFramesInInstance_ThenServerShouldReturnRequestedFrames()
        {
            var       studyInstanceUid = TestUidGenerator.Generate();
            DicomFile dicomFile1       = Samples.CreateRandomDicomFileWithPixelData(studyInstanceUid, frames: 2);
            var       dicomInstance    = dicomFile1.Dataset.ToInstanceIdentifier();
            await _client.StoreAsync(new[] { dicomFile1 }, studyInstanceUid);

            DicomWebResponse <IReadOnlyList <Stream> > frames = await _client.RetrieveFramesAsync(dicomInstance.StudyInstanceUid, dicomInstance.SeriesInstanceUid, dicomInstance.SopInstanceUid, frames : new[] { 1, 2 });

            Assert.NotNull(frames);
            Assert.Equal(HttpStatusCode.OK, frames.StatusCode);
            Assert.Equal(2, frames.Value.Count);
            Assert.Equal(KnownContentTypes.MultipartRelated, frames.Content.Headers.ContentType.MediaType);
            AssertPixelDataEqual(DicomPixelData.Create(dicomFile1.Dataset).GetFrame(0), frames.Value[0]);
            AssertPixelDataEqual(DicomPixelData.Create(dicomFile1.Dataset).GetFrame(1), frames.Value[1]);
        }
Example #14
0
 public async Task <DicomWebResponse <DicomDataset> > StoreAsync(DicomFile dicomFile, string studyInstanceUid = default, string partitionName = default, CancellationToken cancellationToken = default)
 {
     EnsureArg.IsNotNull(dicomFile, nameof(dicomFile));
     _instanceIds.Add(DicomInstanceId.FromDicomFile(dicomFile, partitionName));
     return(await _dicomWebClient.StoreAsync(dicomFile, studyInstanceUid, partitionName, cancellationToken));
 }