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(); }
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); }
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(); }
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); }
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); }
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); }
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; } }
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); }
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); }
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); }
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)); }