Esempio n. 1
0
        public async Task GivenStoredInstancesWithFrames_WhenRetrieveRequestForFrames_ThenFramesInInstanceAreRetrievedSuccesfully()
        {
            // Add multiple instances to validate that we return the requested instance and ignore the other(s).
            List <VersionedInstanceIdentifier> versionedInstanceIdentifiers = SetupInstanceIdentifiersList(ResourceType.Frames);
            var framesToRequest = new List <int> {
                1, 2
            };

            // For the first instance identifier, set up the fileStore to return a stream containing a file associated with the identifier.
            KeyValuePair <DicomFile, Stream> streamAndStoredFile = StreamAndStoredFileFromDataset(GenerateDatasetsFromIdentifiers(versionedInstanceIdentifiers.First()), frames: 3).Result;

            _fileStore.GetFileAsync(versionedInstanceIdentifiers.First(), DefaultCancellationToken).Returns(streamAndStoredFile.Value);

            // Setup frame handler to return the frames as streams from the file.
            Stream[] frames = framesToRequest.Select(f => GetFrameFromFile(streamAndStoredFile.Key.Dataset, f)).ToArray();
            var      retrieveResourceRequest = new RetrieveResourceRequest(_studyInstanceUid, _firstSeriesInstanceUid, _sopInstanceUid, framesToRequest, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetFrame() });

            _dicomFrameHandler.GetFramesResourceAsync(streamAndStoredFile.Value, retrieveResourceRequest.Frames, true, "*").Returns(frames);

            RetrieveResourceResponse response = await _retrieveResourceService.GetInstanceResourceAsync(
                retrieveResourceRequest,
                DefaultCancellationToken);

            // Validate response status code and ensure response streams has expected frames - it should be equivalent to what the store was set up to return.
            AssertPixelDataEqual(DicomPixelData.Create(streamAndStoredFile.Key.Dataset).GetFrame(framesToRequest[0]), response.ResponseStreams.ToList()[0]);
            AssertPixelDataEqual(DicomPixelData.Create(streamAndStoredFile.Key.Dataset).GetFrame(framesToRequest[1]), response.ResponseStreams.ToList()[1]);

            streamAndStoredFile.Value.Dispose();
        }
Esempio n. 2
0
        public async Task GivenARequestWithInvalidInstanceIdentifier_WhenRetrievingInstance_ThenDicomInvalidIdentifierExceptionIsThrown(string sopInstanceUid)
        {
            RetrieveResourceRequest request = new RetrieveResourceRequest(TestUidGenerator.Generate(), TestUidGenerator.Generate(), sopInstanceUid, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetInstance() });
            var ex = await Assert.ThrowsAsync <InvalidIdentifierException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));

            Assert.Equal($"DICOM Identifier 'SopInstanceUid' value '{sopInstanceUid.Trim()}' is invalid. Value length should not exceed the maximum length of 64 characters. Value should contain characters in '0'-'9' and '.'. Each component must start with non-zero number.", ex.Message);
        }
Esempio n. 3
0
        public async Task GivenStoredInstancesWithFrames_WhenRetrieveRequestForNonExistingFrame_ThenNotFoundIsThrown()
        {
            // Add multiple instances to validate that we evaluate the requested instance and ignore the other(s).
            List <VersionedInstanceIdentifier> versionedInstanceIdentifiers = SetupInstanceIdentifiersList(ResourceType.Frames);
            var framesToRequest = new List <int> {
                1, 4
            };

            // For the instance, set up the fileStore to return a stream containing the file associated with the identifier with 3 frames.
            Stream streamOfStoredFiles = StreamAndStoredFileFromDataset(GenerateDatasetsFromIdentifiers(versionedInstanceIdentifiers.First()), frames: 3).Result.Value;

            _fileStore.GetFileAsync(versionedInstanceIdentifiers.First(), DefaultCancellationToken).Returns(streamOfStoredFiles);

            var retrieveResourceRequest = new RetrieveResourceRequest(_studyInstanceUid, _firstSeriesInstanceUid, _sopInstanceUid, framesToRequest, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetFrame() });

            _dicomFrameHandler.GetFramesResourceAsync(streamOfStoredFiles, retrieveResourceRequest.Frames, true, "*").Throws(new FrameNotFoundException());

            // Request 2 frames - one which exists and one which doesn't.
            await Assert.ThrowsAsync <FrameNotFoundException>(() => _retrieveResourceService.GetInstanceResourceAsync(
                                                                  retrieveResourceRequest,
                                                                  DefaultCancellationToken));

            // Dispose the stream.
            streamOfStoredFiles.Dispose();
        }
Esempio n. 4
0
        public async Task GivenARequestWithInvalidStudyAndSeriesIdentifiers_WhenRetrievingSeries_ThenDicomInvalidIdentifierExceptionIsThrown(string studyInstanceUid, string seriesInstanceUid)
        {
            EnsureArg.IsNotNull(studyInstanceUid, nameof(studyInstanceUid));
            RetrieveResourceRequest request = new RetrieveResourceRequest(studyInstanceUid, seriesInstanceUid, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetSeries() });
            var ex = await Assert.ThrowsAsync <InvalidIdentifierException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));

            Assert.Equal($"DICOM Identifier 'StudyInstanceUid' value '{studyInstanceUid.Trim()}' is invalid. Value length should not exceed the maximum length of 64 characters. Value should contain characters in '0'-'9' and '.'. Each component must start with non-zero number.", ex.Message);
        }
Esempio n. 5
0
        public async Task GivenIncorrectTransferSyntax_WhenRetrievingStudy_ThenDicomBadRequestExceptionIsThrownAsync(string transferSyntax)
        {
            var request = new RetrieveResourceRequest(TestUidGenerator.Generate(), new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetInstance(transferSyntax: transferSyntax) });

            var ex = await Assert.ThrowsAsync <BadRequestException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));

            Assert.Equal("The specified Transfer Syntax value is not valid.", ex.Message);
        }
Esempio n. 6
0
 public async Task GivenARequestWithInvalidInstanceIdentifier_WhenRetrievingFrames_ThenDicomInvalidIdentifierExceptionIsThrown(string sopInstanceUid)
 {
     EnsureArg.IsNotNull(sopInstanceUid, nameof(sopInstanceUid));
     RetrieveResourceRequest request = new RetrieveResourceRequest(TestUidGenerator.Generate(), TestUidGenerator.Generate(), sopInstanceUid, new List <int> {
         1
     }, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetFrame() });
     await Assert.ThrowsAsync <InvalidIdentifierException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));
 }
        public void GivenRetrieveResourcesRequestForSeries_WhenConstructed_ThenSeriesResourceTypeIsSet()
        {
            var request = new RetrieveResourceRequest(
                TestUidGenerator.Generate(),
                TestUidGenerator.Generate(),
                new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetSeries(transferSyntax: string.Empty) });

            Assert.Equal(ResourceType.Series, request.ResourceType);
        }
Esempio n. 8
0
        public async Task <RetrieveResourceResponse> GetInstanceResourceAsync(RetrieveResourceRequest message, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(message, nameof(message));

            try
            {
                AcceptHeaderDescriptor acceptHeaderDescriptor;
                string transferSyntax = _retrieveTransferSyntaxHandler.GetTransferSyntax(message.ResourceType, message.AcceptHeaders, out acceptHeaderDescriptor);
                bool   isOriginalTransferSyntaxRequested = DicomTransferSyntaxUids.IsOriginalTransferSyntaxRequested(transferSyntax);

                IEnumerable <VersionedInstanceIdentifier> retrieveInstances = await _instanceStore.GetInstancesToRetrieve(
                    message.ResourceType, message.StudyInstanceUid, message.SeriesInstanceUid, message.SopInstanceUid, cancellationToken);

                if (!retrieveInstances.Any())
                {
                    throw new InstanceNotFoundException();
                }

                Stream[] resultStreams = await Task.WhenAll(
                    retrieveInstances.Select(x => _blobDataStore.GetFileAsync(x, cancellationToken)));

                if (message.ResourceType == ResourceType.Frames)
                {
                    return(new RetrieveResourceResponse(
                               await _frameHandler.GetFramesResourceAsync(
                                   resultStreams.Single(), message.Frames, isOriginalTransferSyntaxRequested, transferSyntax),
                               acceptHeaderDescriptor.MediaType));
                }
                else
                {
                    if (!isOriginalTransferSyntaxRequested)
                    {
                        resultStreams = await Task.WhenAll(resultStreams.Select(x => _transcoder.TranscodeFileAsync(x, transferSyntax)));
                    }

                    resultStreams = resultStreams.Select(stream =>
                                                         new LazyTransformReadOnlyStream <Stream>(
                                                             stream,
                                                             s => ResetDicomFileStream(s))).ToArray();
                }

                return(new RetrieveResourceResponse(resultStreams, acceptHeaderDescriptor.MediaType));
            }
            catch (DataStoreException e)
            {
                // Log request details associated with exception. Note that the details are not for the store call that failed but for the request only.
                _logger.LogError(
                    e,
                    string.Format(
                        "Error retrieving dicom resource. StudyInstanceUid: {0} SeriesInstanceUid: {1} SopInstanceUid: {2}",
                        message.StudyInstanceUid,
                        message.SeriesInstanceUid,
                        message.SopInstanceUid));

                throw;
            }
        }
Esempio n. 9
0
        public async Task GivenNoFrames_WhenRetrievingFrames_ThenDicomBadRequestExceptionIsThrownAsync(int[] frames)
        {
            const string expectedErrorMessage = "The specified frames value is not valid. At least one frame must be present, and all requested frames must have value greater than 0.";
            var          request = new RetrieveResourceRequest(
                studyInstanceUid: TestUidGenerator.Generate(),
                seriesInstanceUid: TestUidGenerator.Generate(),
                sopInstanceUid: TestUidGenerator.Generate(),
                frames: frames,
                acceptHeaders: new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetFrame() });

            var ex = await Assert.ThrowsAsync <BadRequestException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));

            Assert.Equal(expectedErrorMessage, ex.Message);
        }
Esempio n. 10
0
        public async Task GivenRepeatedIdentifiers_WhenRetrievingFrames_ThenDicomBadRequestExceptionIsThrownAsync(
            string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid)
        {
            const string expectedErrorMessage = "The values for StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID must be unique.";
            var          request = new RetrieveResourceRequest(
                studyInstanceUid: studyInstanceUid,
                seriesInstanceUid: seriesInstanceUid,
                sopInstanceUid: sopInstanceUid,
                frames: new int[] { 1 },
                acceptHeaders: new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetFrame() });

            var ex = await Assert.ThrowsAsync <BadRequestException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));

            Assert.Equal(expectedErrorMessage, ex.Message);
        }
Esempio n. 11
0
        public async Task GivenARequestWithValidInstanceIdentifier_WhenRetrievingFrames_ThenNoExceptionIsThrown()
        {
            string studyInstanceUid  = TestUidGenerator.Generate();
            string seriesInstanceUid = TestUidGenerator.Generate();
            string sopInstanceUid    = TestUidGenerator.Generate();

            RetrieveResourceResponse expectedResponse = new RetrieveResourceResponse(Enumerable.Empty <Stream>(), KnownContentTypes.ApplicationOctetStream);
            RetrieveResourceRequest  request          = new RetrieveResourceRequest(studyInstanceUid, seriesInstanceUid, sopInstanceUid, new List <int> {
                1
            }, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetFrame() });

            _retrieveResourceService.GetInstanceResourceAsync(request, CancellationToken.None).Returns(expectedResponse);

            RetrieveResourceResponse response = await _retrieveResourceHandler.Handle(request, CancellationToken.None);

            Assert.Same(expectedResponse, response);
        }
Esempio n. 12
0
 public async Task GivenARequestWithInvalidStudyAndSeriesIdentifiers_WhenRetrievingSeries_ThenDicomInvalidIdentifierExceptionIsThrown(string studyInstanceUid, string seriesInstanceUid)
 {
     EnsureArg.IsNotNull(studyInstanceUid, nameof(studyInstanceUid));
     RetrieveResourceRequest request = new RetrieveResourceRequest(studyInstanceUid, seriesInstanceUid, new[] { AcceptHeaderHelpers.CreateAcceptHeaderForGetSeries() });
     await Assert.ThrowsAsync <InvalidIdentifierException>(() => _retrieveResourceHandler.Handle(request, CancellationToken.None));
 }